summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/protocol.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/protocol.sgml')
-rw-r--r--doc/src/sgml/protocol.sgml7693
1 files changed, 7693 insertions, 0 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
new file mode 100644
index 0000000..cf1fadc
--- /dev/null
+++ b/doc/src/sgml/protocol.sgml
@@ -0,0 +1,7693 @@
+<!-- doc/src/sgml/protocol.sgml -->
+
+<chapter id="protocol">
+ <title>Frontend/Backend Protocol</title>
+
+ <indexterm zone="protocol">
+ <primary>protocol</primary>
+ <secondary>frontend-backend</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> uses a message-based protocol
+ for communication between frontends and backends (clients and servers).
+ The protocol is supported over <acronym>TCP/IP</acronym> and also over
+ Unix-domain sockets. Port number 5432 has been registered with IANA as
+ the customary TCP port number for servers supporting this protocol, but
+ in practice any non-privileged port number can be used.
+ </para>
+
+ <para>
+ This document describes version 3.0 of the protocol, implemented in
+ <productname>PostgreSQL</productname> 7.4 and later. For descriptions
+ of the earlier protocol versions, see previous releases of the
+ <productname>PostgreSQL</productname> documentation. A single server
+ can support multiple protocol versions. The initial startup-request
+ message tells the server which protocol version the client is attempting to
+ use. If the major version requested by the client is not supported by
+ the server, the connection will be rejected (for example, this would occur
+ if the client requested protocol version 4.0, which does not exist as of
+ this writing). If the minor version requested by the client is not
+ supported by the server (e.g., the client requests version 3.1, but the
+ server supports only 3.0), the server may either reject the connection or
+ may respond with a NegotiateProtocolVersion message containing the highest
+ minor protocol version which it supports. The client may then choose either
+ to continue with the connection using the specified protocol version or
+ to abort the connection.
+ </para>
+
+ <para>
+ In order to serve multiple clients efficiently, the server launches
+ a new <quote>backend</quote> process for each client.
+ In the current implementation, a new child
+ process is created immediately after an incoming connection is detected.
+ This is transparent to the protocol, however. For purposes of the
+ protocol, the terms <quote>backend</quote> and <quote>server</quote> are
+ interchangeable; likewise <quote>frontend</quote> and <quote>client</quote>
+ are interchangeable.
+ </para>
+
+ <sect1 id="protocol-overview">
+ <title>Overview</title>
+
+ <para>
+ The protocol has separate phases for startup and normal operation.
+ In the startup phase, the frontend opens a connection to the server
+ and authenticates itself to the satisfaction of the server. (This might
+ involve a single message, or multiple messages depending on the
+ authentication method being used.) If all goes well, the server then sends
+ status information to the frontend, and finally enters normal operation.
+ Except for the initial startup-request message, this part of the
+ protocol is driven by the server.
+ </para>
+
+ <para>
+ During normal operation, the frontend sends queries and
+ other commands to the backend, and the backend sends back query results
+ and other responses. There are a few cases (such as <command>NOTIFY</command>)
+ wherein the
+ backend will send unsolicited messages, but for the most part this portion
+ of a session is driven by frontend requests.
+ </para>
+
+ <para>
+ Termination of the session is normally by frontend choice, but can be
+ forced by the backend in certain cases. In any case, when the backend
+ closes the connection, it will roll back any open (incomplete) transaction
+ before exiting.
+ </para>
+
+ <para>
+ Within normal operation, SQL commands can be executed through either of
+ two sub-protocols. In the <quote>simple query</quote> protocol, the frontend
+ just sends a textual query string, which is parsed and immediately
+ executed by the backend. In the <quote>extended query</quote> protocol,
+ processing of queries is separated into multiple steps: parsing,
+ binding of parameter values, and execution. This offers flexibility
+ and performance benefits, at the cost of extra complexity.
+ </para>
+
+ <para>
+ Normal operation has additional sub-protocols for special operations
+ such as <command>COPY</command>.
+ </para>
+
+ <sect2 id="protocol-message-concepts">
+ <title>Messaging Overview</title>
+
+ <para>
+ All communication is through a stream of messages. The first byte of a
+ message identifies the message type, and the next four bytes specify the
+ length of the rest of the message (this length count includes itself, but
+ not the message-type byte). The remaining contents of the message are
+ determined by the message type. For historical reasons, the very first
+ message sent by the client (the startup message) has no initial
+ message-type byte.
+ </para>
+
+ <para>
+ To avoid losing synchronization with the message stream, both servers and
+ clients typically read an entire message into a buffer (using the byte
+ count) before attempting to process its contents. This allows easy
+ recovery if an error is detected while processing the contents. In
+ extreme situations (such as not having enough memory to buffer the
+ message), the receiver can use the byte count to determine how much
+ input to skip before it resumes reading messages.
+ </para>
+
+ <para>
+ Conversely, both servers and clients must take care never to send an
+ incomplete message. This is commonly done by marshaling the entire message
+ in a buffer before beginning to send it. If a communications failure
+ occurs partway through sending or receiving a message, the only sensible
+ response is to abandon the connection, since there is little hope of
+ recovering message-boundary synchronization.
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-query-concepts">
+ <title>Extended Query Overview</title>
+
+ <para>
+ In the extended-query protocol, execution of SQL commands is divided
+ into multiple steps. The state retained between steps is represented
+ by two types of objects: <firstterm>prepared statements</firstterm> and
+ <firstterm>portals</firstterm>. A prepared statement represents the result of
+ parsing and semantic analysis of a textual query string.
+ A prepared statement is not in itself ready to execute, because it might
+ lack specific values for <firstterm>parameters</firstterm>. A portal represents
+ a ready-to-execute or already-partially-executed statement, with any
+ missing parameter values filled in. (For <command>SELECT</command> statements,
+ a portal is equivalent to an open cursor, but we choose to use a different
+ term since cursors don't handle non-<command>SELECT</command> statements.)
+ </para>
+
+ <para>
+ The overall execution cycle consists of a <firstterm>parse</firstterm> step,
+ which creates a prepared statement from a textual query string; a
+ <firstterm>bind</firstterm> step, which creates a portal given a prepared
+ statement and values for any needed parameters; and an
+ <firstterm>execute</firstterm> step that runs a portal's query. In the case of
+ a query that returns rows (<command>SELECT</command>, <command>SHOW</command>, etc),
+ the execute step can be told to fetch only
+ a limited number of rows, so that multiple execute steps might be needed
+ to complete the operation.
+ </para>
+
+ <para>
+ The backend can keep track of multiple prepared statements and portals
+ (but note that these exist only within a session, and are never shared
+ across sessions). Existing prepared statements and portals are
+ referenced by names assigned when they were created. In addition,
+ an <quote>unnamed</quote> prepared statement and portal exist. Although these
+ behave largely the same as named objects, operations on them are optimized
+ for the case of executing a query only once and then discarding it,
+ whereas operations on named objects are optimized on the expectation
+ of multiple uses.
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-format-codes">
+ <title>Formats and Format Codes</title>
+
+ <para>
+ Data of a particular data type might be transmitted in any of several
+ different <firstterm>formats</firstterm>. As of <productname>PostgreSQL</productname> 7.4
+ the only supported formats are <quote>text</quote> and <quote>binary</quote>,
+ but the protocol makes provision for future extensions. The desired
+ format for any value is specified by a <firstterm>format code</firstterm>.
+ Clients can specify a format code for each transmitted parameter value
+ and for each column of a query result. Text has format code zero,
+ binary has format code one, and all other format codes are reserved
+ for future definition.
+ </para>
+
+ <para>
+ The text representation of values is whatever strings are produced
+ and accepted by the input/output conversion functions for the
+ particular data type. In the transmitted representation, there is
+ no trailing null character; the frontend must add one to received
+ values if it wants to process them as C strings.
+ (The text format does not allow embedded nulls, by the way.)
+ </para>
+
+ <para>
+ Binary representations for integers use network byte order (most
+ significant byte first). For other data types consult the documentation
+ or source code to learn about the binary representation. Keep in mind
+ that binary representations for complex data types might change across
+ server versions; the text format is usually the more portable choice.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="protocol-flow">
+ <title>Message Flow</title>
+
+ <para>
+ This section describes the message flow and the semantics of each
+ message type. (Details of the exact representation of each message
+ appear in <xref linkend="protocol-message-formats"/>.) There are
+ several different sub-protocols depending on the state of the
+ connection: start-up, query, function call,
+ <command>COPY</command>, and termination. There are also special
+ provisions for asynchronous operations (including notification
+ responses and command cancellation), which can occur at any time
+ after the start-up phase.
+ </para>
+
+ <sect2>
+ <title>Start-up</title>
+
+ <para>
+ To begin a session, a frontend opens a connection to the server and sends
+ a startup message. This message includes the names of the user and of the
+ database the user wants to connect to; it also identifies the particular
+ protocol version to be used. (Optionally, the startup message can include
+ additional settings for run-time parameters.)
+ The server then uses this information and
+ the contents of its configuration files (such as
+ <filename>pg_hba.conf</filename>) to determine
+ whether the connection is provisionally acceptable, and what additional
+ authentication is required (if any).
+ </para>
+
+ <para>
+ The server then sends an appropriate authentication request message,
+ to which the frontend must reply with an appropriate authentication
+ response message (such as a password).
+ For all authentication methods except GSSAPI, SSPI and SASL, there is at
+ most one request and one response. In some methods, no response
+ at all is needed from the frontend, and so no authentication request
+ occurs. For GSSAPI, SSPI and SASL, multiple exchanges of packets may be
+ needed to complete the authentication.
+ </para>
+
+ <para>
+ The authentication cycle ends with the server either rejecting the
+ connection attempt (ErrorResponse), or sending AuthenticationOk.
+ </para>
+
+ <para>
+ The possible messages from the server in this phase are:
+
+ <variablelist>
+ <varlistentry>
+ <term>ErrorResponse</term>
+ <listitem>
+ <para>
+ The connection attempt has been rejected.
+ The server then immediately closes the connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationOk</term>
+ <listitem>
+ <para>
+ The authentication exchange is successfully completed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationKerberosV5</term>
+ <listitem>
+ <para>
+ The frontend must now take part in a Kerberos V5
+ authentication dialog (not described here, part of the
+ Kerberos specification) with the server. If this is
+ successful, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. This is no
+ longer supported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationCleartextPassword</term>
+ <listitem>
+ <para>
+ The frontend must now send a PasswordMessage containing the
+ password in clear-text form. If
+ this is the correct password, the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationMD5Password</term>
+ <listitem>
+ <para>
+ The frontend must now send a PasswordMessage containing the
+ password (with user name) encrypted via MD5, then encrypted
+ again using the 4-byte random salt specified in the
+ AuthenticationMD5Password message. If this is the correct
+ password, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. The actual
+ PasswordMessage can be computed in SQL as <literal>concat('md5',
+ md5(concat(md5(concat(password, username)), random-salt)))</literal>.
+ (Keep in mind the <function>md5()</function> function returns its
+ result as a hex string.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSCMCredential</term>
+ <listitem>
+ <para>
+ This response is only possible for local Unix-domain connections
+ on platforms that support SCM credential messages. The frontend
+ must issue an SCM credential message and then send a single data
+ byte. (The contents of the data byte are uninteresting; it's
+ only used to ensure that the server waits long enough to receive
+ the credential message.) If the credential is acceptable,
+ the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ (This message type is only issued by pre-9.1 servers. It may
+ eventually be removed from the protocol specification.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationGSS</term>
+ <listitem>
+ <para>
+ The frontend must now initiate a GSSAPI negotiation. The frontend
+ will send a GSSResponse message with the first part of the GSSAPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSSPI</term>
+ <listitem>
+ <para>
+ The frontend must now initiate an SSPI negotiation. The frontend
+ will send a GSSResponse with the first part of the SSPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </para>
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>AuthenticationGSSContinue</term>
+ <listitem>
+ <para>
+ This message contains the response data from the previous step
+ of GSSAPI or SSPI negotiation (AuthenticationGSS, AuthenticationSSPI
+ or a previous AuthenticationGSSContinue). If the GSSAPI
+ or SSPI data in this message
+ indicates more data is needed to complete the authentication,
+ the frontend must send that data as another GSSResponse message. If
+ GSSAPI or SSPI authentication is completed by this message, the server
+ will next send AuthenticationOk to indicate successful authentication
+ or ErrorResponse to indicate failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASL</term>
+ <listitem>
+ <para>
+ The frontend must now initiate a SASL negotiation, using one of the
+ SASL mechanisms listed in the message. The frontend will send a
+ SASLInitialResponse with the name of the selected mechanism, and the
+ first part of the SASL data stream in response to this. If further
+ messages are needed, the server will respond with
+ AuthenticationSASLContinue. See <xref linkend="sasl-authentication"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASLContinue</term>
+ <listitem>
+ <para>
+ This message contains challenge data from the previous step of SASL
+ negotiation (AuthenticationSASL, or a previous
+ AuthenticationSASLContinue). The frontend must respond with a
+ SASLResponse message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASLFinal</term>
+ <listitem>
+ <para>
+ SASL authentication has completed with additional mechanism-specific
+ data for the client. The server will next send AuthenticationOk to
+ indicate successful authentication, or an ErrorResponse to indicate
+ failure. This message is sent only if the SASL mechanism specifies
+ additional data to be sent from server to client at completion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NegotiateProtocolVersion</term>
+ <listitem>
+ <para>
+ The server does not support the minor protocol version requested
+ by the client, but does support an earlier version of the protocol;
+ this message indicates the highest supported minor version. This
+ message will also be sent if the client requested unsupported protocol
+ options (i.e., beginning with <literal>_pq_.</literal>) in the
+ startup packet. This message will be followed by an ErrorResponse or
+ a message indicating the success or failure of authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ If the frontend does not support the authentication method
+ requested by the server, then it should immediately close the
+ connection.
+ </para>
+
+ <para>
+ After having received AuthenticationOk, the frontend must wait
+ for further messages from the server. In this phase a backend process
+ is being started, and the frontend is just an interested bystander.
+ It is still possible for the startup attempt
+ to fail (ErrorResponse) or the server to decline support for the requested
+ minor protocol version (NegotiateProtocolVersion), but in the normal case
+ the backend will send some ParameterStatus messages, BackendKeyData, and
+ finally ReadyForQuery.
+ </para>
+
+ <para>
+ During this phase the backend will attempt to apply any additional
+ run-time parameter settings that were given in the startup message.
+ If successful, these values become session defaults. An error causes
+ ErrorResponse and exit.
+ </para>
+
+ <para>
+ The possible messages from the backend in this phase are:
+
+ <variablelist>
+ <varlistentry>
+ <term>BackendKeyData</term>
+ <listitem>
+ <para>
+ This message provides secret-key data that the frontend must
+ save if it wants to be able to issue cancel requests later.
+ The frontend should not respond to this message, but should
+ continue listening for a ReadyForQuery message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ParameterStatus</term>
+ <listitem>
+ <para>
+ This message informs the frontend about the current (initial)
+ setting of backend parameters, such as <xref
+ linkend="guc-client-encoding"/> or <xref linkend="guc-datestyle"/>.
+ The frontend can ignore this message, or record the settings
+ for its future use; see <xref linkend="protocol-async"/> for
+ more details. The frontend should not respond to this
+ message, but should continue listening for a ReadyForQuery
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ReadyForQuery</term>
+ <listitem>
+ <para>
+ Start-up is completed. The frontend can now issue commands.
+ </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 can 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 might
+ 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</command> query (or other queries that
+ return row sets, such as <command>EXPLAIN</command> or <command>SHOW</command>)
+ normally consists of RowDescription, zero or more
+ DataRow messages, and then CommandComplete.
+ <command>COPY</command> 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
+ might 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</command> from a cursor
+ declared with the <literal>BINARY</literal> 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 might 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>
+
+ <sect3 id="protocol-flow-multi-statement">
+ <title>Multiple Statements in a Simple Query</title>
+
+ <para>
+ When a simple Query message contains more than one SQL statement
+ (separated by semicolons), those statements are executed as a single
+ transaction, unless explicit transaction control commands are included
+ to force a different behavior. For example, if the message contains
+<programlisting>
+INSERT INTO mytable VALUES(1);
+SELECT 1/0;
+INSERT INTO mytable VALUES(2);
+</programlisting>
+ then the divide-by-zero failure in the <command>SELECT</command> will force
+ rollback of the first <command>INSERT</command>. Furthermore, because
+ execution of the message is abandoned at the first error, the second
+ <command>INSERT</command> is never attempted at all.
+ </para>
+
+ <para>
+ If instead the message contains
+<programlisting>
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELECT 1/0;
+</programlisting>
+ then the first <command>INSERT</command> is committed by the
+ explicit <command>COMMIT</command> command. The second <command>INSERT</command>
+ and the <command>SELECT</command> are still treated as a single transaction,
+ so that the divide-by-zero failure will roll back the
+ second <command>INSERT</command>, but not the first one.
+ </para>
+
+ <para>
+ This behavior is implemented by running the statements in a
+ multi-statement Query message in an <firstterm>implicit transaction
+ block</firstterm> unless there is some explicit transaction block for them to
+ run in. The main difference between an implicit transaction block and
+ a regular one is that an implicit block is closed automatically at the
+ end of the Query message, either by an implicit commit if there was no
+ error, or an implicit rollback if there was an error. This is similar
+ to the implicit commit or rollback that happens for a statement
+ executed by itself (when not in a transaction block).
+ </para>
+
+ <para>
+ If the session is already in a transaction block, as a result of
+ a <command>BEGIN</command> in some previous message, then the Query message
+ simply continues that transaction block, whether the message contains
+ one statement or several. However, if the Query message contains
+ a <command>COMMIT</command> or <command>ROLLBACK</command> closing the existing
+ transaction block, then any following statements are executed in an
+ implicit transaction block.
+ Conversely, if a <command>BEGIN</command> appears in a multi-statement Query
+ message, then it starts a regular transaction block that will only be
+ terminated by an explicit <command>COMMIT</command> or <command>ROLLBACK</command>,
+ whether that appears in this Query message or a later one.
+ If the <command>BEGIN</command> follows some statements that were executed as
+ an implicit transaction block, those statements are not immediately
+ committed; in effect, they are retroactively included into the new
+ regular transaction block.
+ </para>
+
+ <para>
+ A <command>COMMIT</command> or <command>ROLLBACK</command> appearing in an implicit
+ transaction block is executed as normal, closing the implicit block;
+ however, a warning will be issued since a <command>COMMIT</command>
+ or <command>ROLLBACK</command> without a previous <command>BEGIN</command> might
+ represent a mistake. If more statements follow, a new implicit
+ transaction block will be started for them.
+ </para>
+
+ <para>
+ Savepoints are not allowed in an implicit transaction block, since
+ they would conflict with the behavior of automatically closing the
+ block upon any error.
+ </para>
+
+ <para>
+ Remember that, regardless of any transaction control commands that may
+ be present, execution of the Query message stops at the first error.
+ Thus for example given
+<programlisting>
+BEGIN;
+SELECT 1/0;
+ROLLBACK;
+</programlisting>
+ in a single Query message, the session will be left inside a failed
+ regular transaction block, since the <command>ROLLBACK</command> is not
+ reached after the divide-by-zero error. Another <command>ROLLBACK</command>
+ will be needed to restore the session to a usable state.
+ </para>
+
+ <para>
+ Another behavior of note is that initial lexical and syntactic
+ analysis is done on the entire query string before any of it is
+ executed. Thus simple errors (such as a misspelled keyword) in later
+ statements can prevent execution of any of the statements. This
+ is normally invisible to users since the statements would all roll
+ back anyway when done as an implicit transaction block. However,
+ it can be visible when attempting to do multiple transactions within a
+ multi-statement Query. For instance, if a typo turned our previous
+ example into
+<programlisting>
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELCT 1/0;<!-- this typo is intentional -->
+</programlisting>
+ then none of the statements would get run, resulting in the visible
+ difference that the first <command>INSERT</command> is not committed.
+ Errors detected at semantic analysis or later, such as a misspelled
+ table or column name, do not have this effect.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="protocol-flow-ext-query">
+ <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 can 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>$</literal><replaceable>n</replaceable>)
+ used in the query string. Another special case is that a parameter's
+ type can be specified as <type>void</type> (that is, the OID of the
+ <type>void</type> pseudo-type). 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</type> 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)</literal> could match a function with
+ two IN and two OUT arguments, if <literal>$3</literal> and <literal>$4</literal>
+ are specified as having type <type>void</type>.
+ </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
+ another 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</command> and <command>EXECUTE</command>.
+ </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</type> 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</literal> attribute in cursor declarations is irrelevant when
+ using extended query protocol.
+ </para>
+ </note>
+
+ <para>
+ Query planning typically occurs when the Bind message is processed.
+ If the prepared statement has no parameters, or is executed repeatedly,
+ the server might save the created plan and re-use it during subsequent
+ Bind messages for the same prepared statement. However, it will do so
+ only if it finds that a generic plan can be created that is not much
+ less efficient than a plan that depends on the specific parameter values
+ supplied. This happens transparently so far as the protocol is concerned.
+ </para>
+
+ <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 another
+ 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</command> and <command>FETCH</command>.
+ </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</quote>).
+ 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>/<command>COMMIT</command> transaction block (<quote>close</quote>
+ 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</emphasis> processing Sync &mdash; this ensures that there is one
+ and only one ReadyForQuery sent for each Sync.)
+ </para>
+
+ <note>
+ <para>
+ Sync does not cause a transaction block opened with <command>BEGIN</command>
+ 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 id="protocol-flow-pipelining">
+ <title>Pipelining</title>
+
+ <indexterm zone="protocol-flow-pipelining">
+ <primary>pipelining</primary>
+ <secondary>protocol specification</secondary>
+ </indexterm>
+
+ <para>
+ Use of the extended query protocol
+ allows <firstterm>pipelining</firstterm>, which means sending a series
+ of queries without waiting for earlier ones to complete. This reduces
+ the number of network round trips needed to complete a given series of
+ operations. However, the user must carefully consider the required
+ behavior if one of the steps fails, since later queries will already
+ be in flight to the server.
+ </para>
+
+ <para>
+ One way to deal with that is to make the whole query series be a
+ single transaction, that is wrap it in <command>BEGIN</command> ...
+ <command>COMMIT</command>. However, this does not help if one wishes
+ for some of the commands to commit independently of others.
+ </para>
+
+ <para>
+ The extended query protocol provides another way to manage this
+ concern, which is to omit sending Sync messages between steps that
+ are dependent. Since, after an error, the backend will skip command
+ messages until it finds Sync, this allows later commands in a pipeline
+ to be skipped automatically when an earlier one fails, without the
+ client having to manage that explicitly with <command>BEGIN</command>
+ and <command>COMMIT</command>. Independently-committable segments
+ of the pipeline can be separated by Sync messages.
+ </para>
+
+ <para>
+ If the client has not issued an explicit <command>BEGIN</command>,
+ then each Sync ordinarily causes an implicit <command>COMMIT</command>
+ if the preceding step(s) succeeded, or an
+ implicit <command>ROLLBACK</command> if they failed. However, there
+ are a few DDL commands (such as <command>CREATE DATABASE</command>)
+ that cannot be executed inside a transaction block. If one of
+ these is executed in a pipeline, it will, upon success, force an
+ immediate commit to preserve database consistency.
+ A Sync immediately following one of these has no effect except to
+ respond with ReadyForQuery.
+ </para>
+
+ <para>
+ When using this method, completion of the pipeline must be determined
+ by counting ReadyForQuery messages and waiting for that to reach the
+ number of Syncs sent. Counting command completion responses is
+ unreliable, since some of the commands may not be executed and thus not
+ produce a completion message.
+ </para>
+ </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, ...)</literal>.
+ 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 can 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> 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</command> 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</command> SQL statement to fail with an
+ error). The backend then reverts to the command-processing mode it was
+ in before the <command>COPY</command> 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> 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> 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</command>.)
+ </para>
+
+ <para>
+ Copy-out mode (data transfer from the server) is initiated when the
+ backend executes a <command>COPY TO STDOUT</command> 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</command> 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 as
+ terminating the copy-out mode.
+ </para>
+
+ <para>
+ It is possible for NoticeResponse and ParameterStatus messages to be
+ interspersed between CopyData messages; frontends must handle these cases,
+ and should be prepared for other asynchronous message types as well (see
+ <xref linkend="protocol-async"/>). Otherwise, any message type other than
+ CopyData or CopyDone may be treated as terminating copy-out mode.
+ </para>
+
+ <para>
+ There is another Copy-related mode called copy-both, which allows
+ high-speed bulk data transfer to <emphasis>and</emphasis> from the server.
+ Copy-both mode is initiated when a backend in walsender mode
+ executes a <command>START_REPLICATION</command> statement. The
+ backend sends a CopyBothResponse message to the frontend. Both
+ the backend and the frontend may then send CopyData messages
+ until either end sends a CopyDone message. After the client
+ sends a CopyDone message, the connection goes from copy-both mode to
+ copy-out mode, and the client may not send any more CopyData messages.
+ Similarly, when the server sends a CopyDone message, the connection
+ goes into copy-in mode, and the server may not send any more CopyData
+ messages. After both sides have sent a CopyDone message, the copy mode
+ is terminated, and the backend reverts to the command-processing mode.
+ In the event of a backend-detected error during copy-both mode,
+ the backend will issue an ErrorResponse message, discard frontend messages
+ until a Sync message is received, and then issue ReadyForQuery and return
+ to normal processing. The frontend should treat receipt of ErrorResponse
+ as terminating the copy in both directions; no CopyDone should be sent
+ in this case. See <xref linkend="protocol-replication"/> for more
+ information on the subprotocol transmitted over copy-both mode.
+ </para>
+
+ <para>
+ The CopyInResponse, CopyOutResponse and CopyBothResponse 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</command>
+ 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</quote> 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</command> SQL command executed by the frontend, and
+ this case is effectively synchronous &mdash; 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 server. 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
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname>,
+ <varname>client_encoding</varname>,
+ <varname>application_name</varname>,
+ <varname>default_transaction_read_only</varname>,
+ <varname>in_hot_standby</varname>,
+ <varname>is_superuser</varname>,
+ <varname>session_authorization</varname>,
+ <varname>DateStyle</varname>,
+ <varname>IntervalStyle</varname>,
+ <varname>TimeZone</varname>,
+ <varname>integer_datetimes</varname>, and
+ <varname>standard_conforming_strings</varname>.
+ (<varname>server_encoding</varname>, <varname>TimeZone</varname>, and
+ <varname>integer_datetimes</varname> were not reported by releases before 8.0;
+ <varname>standard_conforming_strings</varname> was not reported by releases
+ before 8.1;
+ <varname>IntervalStyle</varname> was not reported by releases before 8.4;
+ <varname>application_name</varname> was not reported by releases before
+ 9.0;
+ <varname>default_transaction_read_only</varname> and
+ <varname>in_hot_standby</varname> were not reported by releases before
+ 14.)
+ Note that
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname> and
+ <varname>integer_datetimes</varname>
+ 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
+ channel 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 might 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>Canceling Requests in Progress</title>
+
+ <para>
+ During the processing of a query, the frontend might 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 might or might not have any effect &mdash; 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 might provide additional flexibility when 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 might 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
+ by recontacting the server if it doesn't want to terminate itself.
+ Closing the connection is also advisable if an unrecognizable message type
+ is received, since this probably indicates loss of message-boundary sync.
+ </para>
+
+ <para>
+ For either normal or abnormal termination, any open transaction is
+ rolled back, not committed. One should note however that if a
+ frontend disconnects while a non-<command>SELECT</command> query
+ is being processed, the backend will probably finish the query
+ before noticing the disconnection. If the query is outside any
+ transaction block (<command>BEGIN</command> ... <command>COMMIT</command>
+ sequence) then its results might be committed before the
+ disconnection is recognized.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><acronym>SSL</acronym> Session Encryption</title>
+
+ <para>
+ If <productname>PostgreSQL</productname> was built with
+ <acronym>SSL</acronym> support, frontend/backend communications
+ can be encrypted using <acronym>SSL</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <productname>PostgreSQL</productname> sessions with
+ <acronym>SSL</acronym>, see <xref linkend="ssl-tcp"/>.
+ </para>
+
+ <para>
+ To initiate an <acronym>SSL</acronym>-encrypted connection, the
+ frontend initially sends an SSLRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <literal>S</literal> or <literal>N</literal>, indicating that it is
+ willing or unwilling to perform <acronym>SSL</acronym>,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <literal>S</literal>, perform an <acronym>SSL</acronym> startup handshake
+ (not described here, part of the <acronym>SSL</acronym>
+ specification) with the server. If this is successful, continue
+ with sending the usual StartupMessage. In this case the
+ StartupMessage and all subsequent data will be
+ <acronym>SSL</acronym>-encrypted. To continue after
+ <literal>N</literal>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue a GSSENCRequest message
+ after an <literal>N</literal> response to try to
+ use <acronym>GSSAPI</acronym> encryption instead
+ of <acronym>SSL</acronym>.)
+ </para>
+
+ <para>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to SSLRequest from the server. This would only occur if
+ the server predates the addition of <acronym>SSL</acronym> support
+ to <productname>PostgreSQL</productname>. (Such servers are now very ancient,
+ and likely do not exist in the wild anymore.)
+ In this case the connection must
+ be closed, but the frontend might choose to open a fresh connection
+ and proceed without requesting <acronym>SSL</acronym>.
+ </para>
+
+ <para>
+ When <acronym>SSL</acronym> encryption can be performed, the server
+ is expected to send only the single <literal>S</literal> byte and then
+ wait for the frontend to initiate an <acronym>SSL</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their SSL library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </para>
+
+ <para>
+ An initial SSLRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </para>
+
+ <para>
+ While the protocol itself does not provide a way for the server to
+ force <acronym>SSL</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><acronym>GSSAPI</acronym> Session Encryption</title>
+
+ <para>
+ If <productname>PostgreSQL</productname> was built with
+ <acronym>GSSAPI</acronym> support, frontend/backend communications
+ can be encrypted using <acronym>GSSAPI</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <productname>PostgreSQL</productname> sessions with
+ <acronym>GSSAPI</acronym>, see <xref linkend="gssapi-enc"/>.
+ </para>
+
+ <para>
+ To initiate a <acronym>GSSAPI</acronym>-encrypted connection, the
+ frontend initially sends a GSSENCRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <literal>G</literal> or <literal>N</literal>, indicating that it
+ is willing or unwilling to perform <acronym>GSSAPI</acronym> encryption,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <literal>G</literal>, using the GSSAPI C bindings as discussed in
+ <ulink url="https://tools.ietf.org/html/rfc2744">RFC 2744</ulink>
+ or equivalent, perform a <acronym>GSSAPI</acronym> initialization by
+ calling <function>gss_init_sec_context()</function> in a loop and sending
+ the result to the server, starting with an empty input and then with each
+ result from the server, until it returns no output. When sending the
+ results of <function>gss_init_sec_context()</function> to the server,
+ prepend the length of the message as a four byte integer in network byte
+ order.
+ To continue after
+ <literal>N</literal>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue an SSLRequest message
+ after an <literal>N</literal> response to try to
+ use <acronym>SSL</acronym> encryption instead
+ of <acronym>GSSAPI</acronym>.)
+ </para>
+
+ <para>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to GSSENCRequest from the server. This would only occur if
+ the server predates the addition of <acronym>GSSAPI</acronym> encryption
+ support to <productname>PostgreSQL</productname>. In this case the
+ connection must be closed, but the frontend might choose to open a fresh
+ connection and proceed without requesting <acronym>GSSAPI</acronym>
+ encryption.
+ </para>
+
+ <para>
+ When <acronym>GSSAPI</acronym> encryption can be performed, the server
+ is expected to send only the single <literal>G</literal> byte and then
+ wait for the frontend to initiate a <acronym>GSSAPI</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their GSSAPI library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </para>
+
+ <para>
+ An initial GSSENCRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </para>
+
+ <para>
+ Once <acronym>GSSAPI</acronym> encryption has been successfully
+ established, use <function>gss_wrap()</function> to
+ encrypt the usual StartupMessage and all subsequent data, prepending the
+ length of the result from <function>gss_wrap()</function> as a four byte
+ integer in network byte order to the actual encrypted payload. Note that
+ the server will only accept encrypted packets from the client which are less
+ than 16kB; <function>gss_wrap_size_limit()</function> should be used by the
+ client to determine the size of the unencrypted message which will fit
+ within this limit and larger messages should be broken up into multiple
+ <function>gss_wrap()</function> calls. Typical segments are 8kB of
+ unencrypted data, resulting in encrypted packets of slightly larger than 8kB
+ but well within the 16kB maximum. The server can be expected to not send
+ encrypted packets of larger than 16kB to the client.
+ </para>
+
+ <para>
+ While the protocol itself does not provide a way for the server to
+ force <acronym>GSSAPI</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </para>
+ </sect2>
+ </sect1>
+
+<sect1 id="sasl-authentication">
+<title>SASL Authentication</title>
+
+<para>
+<firstterm>SASL</firstterm> is a framework for authentication in connection-oriented
+protocols. At the moment, <productname>PostgreSQL</productname> implements two SASL
+authentication mechanisms, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. More
+might be added in the future. The below steps illustrate how SASL
+authentication is performed in general, while the next subsection gives
+more details on SCRAM-SHA-256 and SCRAM-SHA-256-PLUS.
+</para>
+
+<procedure>
+<title>SASL Authentication Message Flow</title>
+
+<step id="sasl-auth-begin">
+<para>
+ To begin a SASL authentication exchange, the server sends an
+ AuthenticationSASL message. It includes a list of SASL authentication
+ mechanisms that the server can accept, in the server's preferred order.
+</para>
+</step>
+
+<step id="sasl-auth-initial-response">
+<para>
+ The client selects one of the supported mechanisms from the list, and sends
+ a SASLInitialResponse message to the server. The message includes the name
+ of the selected mechanism, and an optional Initial Client Response, if the
+ selected mechanism uses that.
+</para>
+</step>
+
+<step id="sasl-auth-continue">
+<para>
+ One or more server-challenge and client-response message will follow. Each
+ server-challenge is sent in an AuthenticationSASLContinue message, followed
+ by a response from client in a SASLResponse message. The particulars of
+ the messages are mechanism specific.
+</para>
+</step>
+
+<step id="sasl-auth-end">
+<para>
+ Finally, when the authentication exchange is completed successfully, the
+ server sends an AuthenticationSASLFinal message, followed
+ immediately by an AuthenticationOk message. The AuthenticationSASLFinal
+ contains additional server-to-client data, whose content is particular to the
+ selected authentication mechanism. If the authentication mechanism doesn't
+ use additional data that's sent at completion, the AuthenticationSASLFinal
+ message is not sent.
+</para>
+</step>
+</procedure>
+
+<para>
+On error, the server can abort the authentication at any stage, and send an
+ErrorMessage.
+</para>
+
+ <sect2 id="sasl-scram-sha-256">
+ <title>SCRAM-SHA-256 Authentication</title>
+
+ <para>
+ The implemented SASL mechanisms at the moment
+ are <literal>SCRAM-SHA-256</literal> and its variant with channel
+ binding <literal>SCRAM-SHA-256-PLUS</literal>. They are described in
+ detail in <ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>
+ and <ulink url="https://tools.ietf.org/html/rfc5802">RFC 5802</ulink>.
+ </para>
+
+ <para>
+When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name
+that the client sends in the <structname>client-first-message</structname>. The user name
+that was already sent in the startup message is used instead.
+<productname>PostgreSQL</productname> supports multiple character encodings, while SCRAM
+dictates UTF-8 to be used for the user name, so it might be impossible to
+represent the PostgreSQL user name in UTF-8.
+ </para>
+
+ <para>
+The SCRAM specification dictates that the password is also in UTF-8, and is
+processed with the <firstterm>SASLprep</firstterm> algorithm.
+<productname>PostgreSQL</productname>, however, does not require UTF-8 to be used for
+the password. When a user's password is set, it is processed with SASLprep
+as if it was in UTF-8, regardless of the actual encoding used. However, if
+it is not a legal UTF-8 byte sequence, or it contains UTF-8 byte sequences
+that are prohibited by the SASLprep algorithm, the raw password will be used
+without SASLprep processing, instead of throwing an error. This allows the
+password to be normalized when it is in UTF-8, but still allows a non-UTF-8
+password to be used, and doesn't require the system to know which encoding
+the password is in.
+ </para>
+
+ <para>
+<firstterm>Channel binding</firstterm> is supported in PostgreSQL builds with
+SSL support. The SASL mechanism name for SCRAM with channel binding is
+<literal>SCRAM-SHA-256-PLUS</literal>. The channel binding type used by
+PostgreSQL is <literal>tls-server-end-point</literal>.
+ </para>
+
+ <para>
+ In <acronym>SCRAM</acronym> without channel binding, the server chooses
+ a random number that is transmitted to the client to be mixed with the
+ user-supplied password in the transmitted password hash. While this
+ prevents the password hash from being successfully retransmitted in
+ a later session, it does not prevent a fake server between the real
+ server and client from passing through the server's random value
+ and successfully authenticating.
+ </para>
+
+ <para>
+ <acronym>SCRAM</acronym> with channel binding prevents such
+ man-in-the-middle attacks by mixing the signature of the server's
+ certificate into the transmitted password hash. While a fake server can
+ retransmit the real server's certificate, it doesn't have access to the
+ private key matching that certificate, and therefore cannot prove it is
+ the owner, causing SSL connection failure.
+ </para>
+
+<procedure>
+<title>Example</title>
+ <step id="scram-begin">
+<para>
+ The server sends an AuthenticationSASL message. It includes a list of
+ SASL authentication mechanisms that the server can accept.
+ This will be <literal>SCRAM-SHA-256-PLUS</literal>
+ and <literal>SCRAM-SHA-256</literal> if the server is built with SSL
+ support, or else just the latter.
+</para>
+</step>
+<step id="scram-client-first">
+<para>
+ The client responds by sending a SASLInitialResponse message, which
+ indicates the chosen mechanism, <literal>SCRAM-SHA-256</literal> or
+ <literal>SCRAM-SHA-256-PLUS</literal>. (A client is free to choose either
+ mechanism, but for better security it should choose the channel-binding
+ variant if it can support it.) In the Initial Client response field, the
+ message contains the SCRAM <structname>client-first-message</structname>.
+ The <structname>client-first-message</structname> also contains the channel
+ binding type chosen by the client.
+</para>
+</step>
+<step id="scram-server-first">
+<para>
+ Server sends an AuthenticationSASLContinue message, with a SCRAM
+ <structname>server-first-message</structname> as the content.
+</para>
+</step>
+<step id="scram-client-final">
+<para>
+ Client sends a SASLResponse message, with SCRAM
+ <structname>client-final-message</structname> as the content.
+</para>
+</step>
+<step id="scram-server-final">
+<para>
+ Server sends an AuthenticationSASLFinal message, with the SCRAM
+ <structname>server-final-message</structname>, followed immediately by
+ an AuthenticationOk message.
+</para>
+</step>
+</procedure>
+</sect2>
+</sect1>
+
+<sect1 id="protocol-replication">
+<title>Streaming Replication Protocol</title>
+
+<para>
+To initiate streaming replication, the frontend sends the
+<literal>replication</literal> parameter in the startup message. A Boolean
+value of <literal>true</literal> (or <literal>on</literal>,
+<literal>yes</literal>, <literal>1</literal>) tells the backend to go into
+physical replication walsender mode, wherein a small set of replication
+commands, shown below, can be issued instead of SQL statements.
+</para>
+
+<para>
+Passing <literal>database</literal> as the value for the
+<literal>replication</literal> parameter instructs the backend to go into
+logical replication walsender mode, connecting to the database specified in
+the <literal>dbname</literal> parameter. In logical replication walsender
+mode, the replication commands shown below as well as normal SQL commands can
+be issued.
+</para>
+
+<para>
+In either physical replication or logical replication walsender mode, only the
+simple query protocol can be used.
+</para>
+
+<para>
+ For the purpose of testing replication commands, you can make a replication
+ connection via <application>psql</application> or any other
+ <application>libpq</application>-using tool with a connection string including
+ the <literal>replication</literal> option,
+ e.g.:
+<programlisting>
+psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
+</programlisting>
+ However, it is often more useful to use
+ <xref linkend="app-pgreceivewal"/> (for physical replication) or
+ <xref linkend="app-pgrecvlogical"/> (for logical replication).
+</para>
+
+<para>
+Replication commands are logged in the server log when
+<xref linkend="guc-log-replication-commands"/> is enabled.
+</para>
+
+<para>
+The commands accepted in replication mode are:
+<variablelist>
+ <varlistentry>
+ <term><literal>IDENTIFY_SYSTEM</literal>
+ <indexterm><primary>IDENTIFY_SYSTEM</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to identify itself. Server replies with a result
+ set of a single row, containing four fields:
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>systemid</literal> (<type>text</type>)
+ </term>
+ <listitem>
+ <para>
+ The unique system identifier identifying the cluster. This
+ can be used to check that the base backup used to initialize the
+ standby came from the same cluster.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>timeline</literal> (<type>int4</type>)
+ </term>
+ <listitem>
+ <para>
+ Current timeline ID. Also useful to check that the standby is
+ consistent with the primary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>xlogpos</literal> (<type>text</type>)
+ </term>
+ <listitem>
+ <para>
+ Current WAL flush location. Useful to get a known location in the
+ write-ahead log where streaming can start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>dbname</literal> (<type>text</type>)
+ </term>
+ <listitem>
+ <para>
+ Database connected to or null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SHOW</literal> <replaceable class="parameter">name</replaceable>
+ <indexterm><primary>SHOW</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to send the current setting of a run-time parameter.
+ This is similar to the SQL command <xref linkend="sql-show"/>.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a run-time parameter. Available parameters are documented
+ in <xref linkend="runtime-config"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TIMELINE_HISTORY</literal> <replaceable class="parameter">tli</replaceable>
+ <indexterm><primary>TIMELINE_HISTORY</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to send over the timeline history file for timeline
+ <replaceable class="parameter">tli</replaceable>. Server replies with a
+ result set of a single row, containing two fields. While the fields
+ are labeled as <type>text</type>, they effectively return raw bytes,
+ with no encoding conversion:
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>filename</literal> (<type>text</type>)
+ </term>
+ <listitem>
+ <para>
+ File name of the timeline history file, e.g., <filename>00000002.history</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>content</literal> (<type>text</type>)
+ </term>
+ <listitem>
+ <para>
+ Contents of the timeline history file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-create-slot" xreflabel="CREATE_REPLICATION_SLOT">
+ <term><literal>CREATE_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> [ <literal>TEMPORARY</literal> ] { <literal>PHYSICAL</literal> [ <literal>RESERVE_WAL</literal> ] | <literal>LOGICAL</literal> <replaceable class="parameter">output_plugin</replaceable> [ <literal>EXPORT_SNAPSHOT</literal> | <literal>NOEXPORT_SNAPSHOT</literal> | <literal>USE_SNAPSHOT</literal> ] }
+ <indexterm><primary>CREATE_REPLICATION_SLOT</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Create a physical or logical replication
+ slot. See <xref linkend="streaming-replication-slots"/> for more about
+ replication slots.
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to create. Must be a valid replication slot
+ name (see <xref linkend="streaming-replication-slots-manipulation"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_plugin</replaceable></term>
+ <listitem>
+ <para>
+ The name of the output plugin used for logical decoding
+ (see <xref linkend="logicaldecoding-output-plugin"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TEMPORARY</literal></term>
+ <listitem>
+ <para>
+ Specify that this replication slot is a temporary one. Temporary
+ slots are not saved to disk and are automatically dropped on error
+ or when the session has finished.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESERVE_WAL</literal></term>
+ <listitem>
+ <para>
+ Specify that this physical replication slot reserves <acronym>WAL</acronym>
+ immediately. Otherwise, <acronym>WAL</acronym> is only reserved upon
+ connection from a streaming replication client.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXPORT_SNAPSHOT</literal></term>
+ <term><literal>NOEXPORT_SNAPSHOT</literal></term>
+ <term><literal>USE_SNAPSHOT</literal></term>
+ <listitem>
+ <para>
+ Decides what to do with the snapshot created during logical slot
+ initialization. <literal>EXPORT_SNAPSHOT</literal>, which is the default,
+ will export the snapshot for use in other sessions. This option can't
+ be used inside a transaction. <literal>USE_SNAPSHOT</literal> will use the
+ snapshot for the current transaction executing the command. This
+ option must be used in a transaction, and
+ <literal>CREATE_REPLICATION_SLOT</literal> must be the first command
+ run in that transaction. Finally, <literal>NOEXPORT_SNAPSHOT</literal> will
+ just use the snapshot for logical decoding as normal but won't do
+ anything else with it.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In response to this command, the server will send a one-row result set
+ containing the following fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>slot_name</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The name of the newly-created replication slot.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>consistent_point</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The WAL location at which the slot became consistent. This is the
+ earliest location from which streaming can start on this replication
+ slot.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>snapshot_name</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The identifier of the snapshot exported by the command. The
+ snapshot is valid until a new command is executed on this connection
+ or the replication connection is closed. Null if the created slot
+ is physical.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>output_plugin</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The name of the output plugin used by the newly-created replication
+ slot. Null if the created slot is physical.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>START_REPLICATION</literal> [ <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable> ] [ <literal>PHYSICAL</literal> ] <replaceable class="parameter">XXX/XXX</replaceable> [ <literal>TIMELINE</literal> <replaceable class="parameter">tli</replaceable> ]
+ <indexterm><primary>START_REPLICATION</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Instructs server to start streaming WAL, starting at
+ WAL location <replaceable class="parameter">XXX/XXX</replaceable>.
+ If <literal>TIMELINE</literal> option is specified,
+ streaming starts on timeline <replaceable class="parameter">tli</replaceable>;
+ otherwise, the server's current timeline is selected. The server can
+ reply with an error, for example if the requested section of WAL has already
+ been recycled. On success, the server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </para>
+
+ <para>
+ If a slot's name is provided
+ via <replaceable class="parameter">slot_name</replaceable>, it will be updated
+ as replication progresses so that the server knows which WAL segments,
+ and if <varname>hot_standby_feedback</varname> is on which transactions,
+ are still needed by the standby.
+ </para>
+
+ <para>
+ If the client requests a timeline that's not the latest but is part of
+ the history of the server, the server will stream all the WAL on that
+ timeline starting from the requested start point up to the point where
+ the server switched to another timeline. If the client requests
+ streaming at exactly the end of an old timeline, the server skips COPY
+ mode entirely.
+ </para>
+
+ <para>
+ After streaming all the WAL on a timeline that is not the latest one,
+ the server will end streaming by exiting the COPY mode. When the client
+ acknowledges this by also exiting COPY mode, the server sends a result
+ set with one row and two columns, indicating the next timeline in this
+ server's history. The first column is the next timeline's ID (type <type>int8</type>), and the
+ second column is the WAL location where the switch happened (type <type>text</type>). Usually,
+ the switch position is the end of the WAL that was streamed, but there
+ are corner cases where the server can send some WAL from the old
+ timeline that it has not itself replayed before promoting. Finally, the
+ server sends two CommandComplete messages (one that ends the CopyData
+ and the other ends the <literal>START_REPLICATION</literal> itself), and
+ is ready to accept a new command.
+ </para>
+
+ <para>
+ WAL data is sent as a series of CopyData messages. (This allows
+ other information to be intermixed; in particular the server can send
+ an ErrorResponse message if it encounters a failure after beginning
+ to stream.) The payload of each CopyData message from server to the
+ client contains a message of one of the following formats:
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ XLogData (B)
+ </term>
+ <listitem>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Byte1('w')
+ </term>
+ <listitem>
+ <para>
+ Identifies the message as WAL data.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The starting point of the WAL data in this message.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The current end of WAL on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte<replaceable>n</replaceable>
+ </term>
+ <listitem>
+ <para>
+ A section of the WAL data stream.
+ </para>
+ <para>
+ A single WAL record is never split across two XLogData messages.
+ When a WAL record crosses a WAL page boundary, and is therefore
+ already split using continuation records, it can be split at the page
+ boundary. In other words, the first main WAL record and its
+ continuation records can be sent in different XLogData messages.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Primary keepalive message (B)
+ </term>
+ <listitem>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Byte1('k')
+ </term>
+ <listitem>
+ <para>
+ Identifies the message as a sender keepalive.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The current end of WAL on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte1
+ </term>
+ <listitem>
+ <para>
+ 1 means that the client should reply to this message as soon as
+ possible, to avoid a timeout disconnect. 0 otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The receiving process can send replies back to the sender at any time,
+ using one of the following message formats (also in the payload of a
+ CopyData message):
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Standby status update (F)
+ </term>
+ <listitem>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Byte1('r')
+ </term>
+ <listitem>
+ <para>
+ Identifies the message as a receiver status update.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 received and written to disk
+ in the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 flushed to disk in
+ the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 applied in the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte1
+ </term>
+ <listitem>
+ <para>
+ If 1, the client requests the server to reply to this message
+ immediately. This can be used to ping the server, to test if
+ the connection is still healthy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Hot Standby feedback message (F)
+ </term>
+ <listitem>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ Byte1('h')
+ </term>
+ <listitem>
+ <para>
+ Identifies the message as a Hot Standby feedback message.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int64
+ </term>
+ <listitem>
+ <para>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int32
+ </term>
+ <listitem>
+ <para>
+ The standby's current global xmin, excluding the catalog_xmin from any
+ replication slots. If both this value and the following
+ catalog_xmin are 0 this is treated as a notification that Hot Standby
+ feedback will no longer be sent on this connection. Later non-zero
+ messages may reinitiate the feedback mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int32
+ </term>
+ <listitem>
+ <para>
+ The epoch of the global xmin xid on the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int32
+ </term>
+ <listitem>
+ <para>
+ The lowest catalog_xmin of any replication slots on the standby. Set to 0
+ if no catalog_xmin exists on the standby or if hot standby feedback is being
+ disabled.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Int32
+ </term>
+ <listitem>
+ <para>
+ The epoch of the catalog_xmin xid on the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>START_REPLICATION</literal> <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable> <literal>LOGICAL</literal> <replaceable class="parameter">XXX/XXX</replaceable> [ ( <replaceable>option_name</replaceable> [ <replaceable>option_value</replaceable> ] [, ...] ) ]</term>
+ <listitem>
+ <para>
+ Instructs server to start streaming WAL for logical replication, starting
+ at WAL location <replaceable class="parameter">XXX/XXX</replaceable>. The server can
+ reply with an error, for example if the requested section of WAL has already
+ been recycled. On success, server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </para>
+
+ <para>
+ The messages inside the CopyBothResponse messages are of the same format
+ documented for <literal>START_REPLICATION ... PHYSICAL</literal>, including
+ two CommandComplete messages.
+ </para>
+
+ <para>
+ The output plugin associated with the selected slot is used
+ to process the output for streaming.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to stream changes from. This parameter is required,
+ and must correspond to an existing logical replication slot created
+ with <literal>CREATE_REPLICATION_SLOT</literal> in
+ <literal>LOGICAL</literal> mode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">XXX/XXX</replaceable></term>
+ <listitem>
+ <para>
+ The WAL location to begin streaming at.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">option_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an option passed to the slot's logical decoding plugin.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">option_value</replaceable></term>
+ <listitem>
+ <para>
+ Optional value, in the form of a string constant, associated with the
+ specified option.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>DROP_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> <optional> <literal>WAIT</literal> </optional>
+ <indexterm><primary>DROP_REPLICATION_SLOT</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Drops a replication slot, freeing any reserved server-side resources.
+ If the slot is a logical slot that was created in a database other than
+ the database the walsender is connected to, this command fails.
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAIT</literal></term>
+ <listitem>
+ <para>
+ This option causes the command to wait if the slot is active until
+ it becomes inactive, instead of the default behavior of raising an
+ error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-base-backup" xreflabel="BASE_BACKUP">
+ <term><literal>BASE_BACKUP</literal> [ <literal>LABEL</literal> <replaceable>'label'</replaceable> ] [ <literal>PROGRESS</literal> ] [ <literal>FAST</literal> ] [ <literal>WAL</literal> ] [ <literal>NOWAIT</literal> ] [ <literal>MAX_RATE</literal> <replaceable>rate</replaceable> ] [ <literal>TABLESPACE_MAP</literal> ] [ <literal>NOVERIFY_CHECKSUMS</literal> ] [ <literal>MANIFEST</literal> <replaceable>manifest_option</replaceable> ] [ <literal>MANIFEST_CHECKSUMS</literal> <replaceable>checksum_algorithm</replaceable> ]
+ <indexterm><primary>BASE_BACKUP</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Instructs the server to start streaming a base backup.
+ The system will automatically be put in backup mode before the backup
+ is started, and taken out of it when the backup is complete. The
+ following options are accepted:
+ <variablelist>
+ <varlistentry>
+ <term><literal>LABEL</literal> <replaceable>'label'</replaceable></term>
+ <listitem>
+ <para>
+ Sets the label of the backup. If none is specified, a backup label
+ of <literal>base backup</literal> will be used. The quoting rules
+ for the label are the same as a standard SQL string with
+ <xref linkend="guc-standard-conforming-strings"/> turned on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROGRESS</literal></term>
+ <listitem>
+ <para>
+ Request information required to generate a progress report. This will
+ send back an approximate size in the header of each tablespace, which
+ can be used to calculate how far along the stream is done. This is
+ calculated by enumerating all the file sizes once before the transfer
+ is even started, and might as such have a negative impact on the
+ performance. In particular, it might take longer before the first data
+ is streamed. Since the database files can change during the backup,
+ the size is only approximate and might both grow and shrink between
+ the time of approximation and the sending of the actual files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FAST</literal></term>
+ <listitem>
+ <para>
+ Request a fast checkpoint.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAL</literal></term>
+ <listitem>
+ <para>
+ Include the necessary WAL segments in the backup. This will include
+ all the files between start and stop backup in the
+ <filename>pg_wal</filename> directory of the base directory tar
+ file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOWAIT</literal></term>
+ <listitem>
+ <para>
+ By default, the backup will wait until the last required WAL
+ segment has been archived, or emit a warning if log archiving is
+ not enabled. Specifying <literal>NOWAIT</literal> disables both
+ the waiting and the warning, leaving the client responsible for
+ ensuring the required log is available.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MAX_RATE</literal> <replaceable>rate</replaceable></term>
+ <listitem>
+ <para>
+ Limit (throttle) the maximum amount of data transferred from server
+ to client per unit of time. The expected unit is kilobytes per second.
+ If this option is specified, the value must either be equal to zero
+ or it must fall within the range from 32 kB through 1 GB (inclusive).
+ If zero is passed or the option is not specified, no restriction is
+ imposed on the transfer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESPACE_MAP</literal></term>
+ <listitem>
+ <para>
+ Include information about symbolic links present in the directory
+ <filename>pg_tblspc</filename> in a file named
+ <filename>tablespace_map</filename>. The tablespace map file includes
+ each symbolic link name as it exists in the directory
+ <filename>pg_tblspc/</filename> and the full path of that symbolic link.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOVERIFY_CHECKSUMS</literal></term>
+ <listitem>
+ <para>
+ By default, checksums are verified during a base backup if they are
+ enabled. Specifying <literal>NOVERIFY_CHECKSUMS</literal> disables
+ this verification.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MANIFEST</literal> <replaceable>manifest_option</replaceable></term>
+ <listitem>
+ <para>
+ When this option is specified with a value of <literal>yes</literal>
+ or <literal>force-encode</literal>, a backup manifest is created
+ and sent along with the backup. The manifest is a list of every
+ file present in the backup with the exception of any WAL files that
+ may be included. It also stores the size, last modification time, and
+ optionally a checksum for each file.
+ A value of <literal>force-encode</literal> forces all filenames
+ to be hex-encoded; otherwise, this type of encoding is performed only
+ for files whose names are non-UTF8 octet sequences.
+ <literal>force-encode</literal> is intended primarily for testing
+ purposes, to be sure that clients which read the backup manifest
+ can handle this case. For compatibility with previous releases,
+ the default is <literal>MANIFEST 'no'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MANIFEST_CHECKSUMS</literal> <replaceable>checksum_algorithm</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the checksum algorithm that should be applied to each file included
+ in the backup manifest. Currently, the available
+ algorithms are <literal>NONE</literal>, <literal>CRC32C</literal>,
+ <literal>SHA224</literal>, <literal>SHA256</literal>,
+ <literal>SHA384</literal>, and <literal>SHA512</literal>.
+ The default is <literal>CRC32C</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ When the backup is started, the server will first send two
+ ordinary result sets, followed by one or more CopyOutResponse
+ results.
+ </para>
+ <para>
+ The first ordinary result set contains the starting position of the
+ backup, in a single row with two columns. The first column contains
+ the start position given in XLogRecPtr format, and the second column
+ contains the corresponding timeline ID.
+ </para>
+ <para>
+ The second ordinary result set has one row for each tablespace.
+ The fields in this row are:
+ <variablelist>
+ <varlistentry>
+ <term><literal>spcoid</literal> (<type>oid</type>)</term>
+ <listitem>
+ <para>
+ The OID of the tablespace, or null if it's the base
+ directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>spclocation</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The full path of the tablespace directory, or null
+ if it's the base directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>size</literal> (<type>int8</type>)</term>
+ <listitem>
+ <para>
+ The approximate size of the tablespace, in kilobytes (1024 bytes),
+ if progress report has been requested; otherwise it's null.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ After the second regular result set, one or more CopyOutResponse results
+ will be sent, one for the main data directory and one for each additional tablespace other
+ than <literal>pg_default</literal> and <literal>pg_global</literal>. The data in
+ the CopyOutResponse results will be a tar format (following the
+ <quote>ustar interchange format</quote> specified in the POSIX 1003.1-2008
+ standard) dump of the tablespace contents, except that the two trailing
+ blocks of zeroes specified in the standard are omitted.
+ After the tar data is complete, and if a backup manifest was requested,
+ another CopyOutResponse result is sent, containing the manifest data for the
+ current base backup. In any case, a final ordinary result set will be
+ sent, containing the WAL end position of the backup, in the same format as
+ the start position.
+ </para>
+
+ <para>
+ The tar archive for the data directory and each tablespace will contain
+ all files in the directories, regardless of whether they are
+ <productname>PostgreSQL</productname> files or other files added to the same
+ directory. The only excluded files are:
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <filename>postmaster.pid</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>postmaster.opts</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_internal.init</filename> (found in multiple directories)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Various temporary files and directories created during the operation
+ of the PostgreSQL server, such as any file or directory beginning
+ with <filename>pgsql_tmp</filename> and temporary relations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Unlogged relations, except for the init fork which is required to
+ recreate the (empty) unlogged relation on recovery.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_wal</filename>, including subdirectories. If the backup is run
+ with WAL files included, a synthesized version of <filename>pg_wal</filename> will be
+ included, but it will only contain the files necessary for the
+ backup to work, not the rest of the contents.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_dynshmem</filename>, <filename>pg_notify</filename>,
+ <filename>pg_replslot</filename>, <filename>pg_serial</filename>,
+ <filename>pg_snapshots</filename>, <filename>pg_stat_tmp</filename>, and
+ <filename>pg_subtrans</filename> are copied as empty directories (even if
+ they are symbolic links).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Files other than regular files and directories, such as symbolic
+ links (other than for the directories listed above) and special
+ device files, are skipped. (Symbolic links
+ in <filename>pg_tblspc</filename> are maintained.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ Owner, group, and file mode are set if the underlying file system on
+ the server supports it.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</para>
+
+</sect1>
+
+<sect1 id="protocol-logical-replication">
+ <title>Logical Streaming Replication Protocol</title>
+
+ <para>
+ This section describes the logical replication protocol, which is the message
+ flow started by the <literal>START_REPLICATION</literal>
+ <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable>
+ <literal>LOGICAL</literal> replication command.
+ </para>
+
+ <para>
+ The logical streaming replication protocol builds on the primitives of
+ the physical streaming replication protocol.
+ </para>
+
+ <sect2 id="protocol-logical-replication-params">
+ <title>Logical Streaming Replication Parameters</title>
+
+ <para>
+ The logical replication <literal>START_REPLICATION</literal> command
+ accepts following parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ proto_version
+ </term>
+ <listitem>
+ <para>
+ Protocol version. Currently versions <literal>1</literal> and
+ <literal>2</literal> are supported. The version <literal>2</literal>
+ is supported only for server version 14 and above, and it allows
+ streaming of large in-progress transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ publication_names
+ </term>
+ <listitem>
+ <para>
+ Comma separated list of publication names for which to subscribe
+ (receive changes). The individual publication names are treated
+ as standard objects names and can be quoted the same as needed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-logical-messages">
+ <title>Logical Replication Protocol Messages</title>
+
+ <para>
+ The individual protocol messages are discussed in the following
+ subsections. Individual messages are described in
+ <xref linkend="protocol-logicalrep-message-formats"/>.
+ </para>
+
+ <para>
+ All top-level protocol messages begin with a message type byte.
+ While represented in code as a character, this is a signed byte with no
+ associated encoding.
+ </para>
+
+ <para>
+ Since the streaming replication protocol supplies a message length there
+ is no need for top-level protocol messages to embed a length in their
+ header.
+ </para>
+
+ </sect2>
+
+ <sect2 id="protocol-logical-messages-flow">
+ <title>Logical Replication Protocol Message Flow</title>
+
+ <para>
+ With the exception of the <literal>START_REPLICATION</literal> command and
+ the replay progress messages, all information flows only from the backend
+ to the frontend.
+ </para>
+
+ <para>
+ The logical replication protocol sends individual transactions one by one.
+ This means that all messages between a pair of Begin and Commit messages
+ belong to the same transaction. It also sends changes of large in-progress
+ transactions between a pair of Stream Start and Stream Stop messages. The
+ last stream of such a transaction contains Stream Commit or Stream Abort
+ message.
+ </para>
+
+ <para>
+ Every sent transaction contains zero or more DML messages (Insert,
+ Update, Delete). In case of a cascaded setup it can also contain Origin
+ messages. The origin message indicates that the transaction originated on
+ different replication node. Since a replication node in the scope of logical
+ replication protocol can be pretty much anything, the only identifier
+ is the origin name. It's downstream's responsibility to handle this as
+ needed (if needed). The Origin message is always sent before any DML
+ messages in the transaction.
+ </para>
+
+ <para>
+ Every DML message contains a relation OID, identifying the publisher's
+ relation that was acted on. Before the first DML message for a given
+ relation OID, a Relation message will be sent, describing the schema of
+ that relation. Subsequently, a new Relation message will be sent if
+ the relation's definition has changed since the last Relation message
+ was sent for it. (The protocol assumes that the client is capable of
+ remembering this metadata for as many relations as needed.)
+ </para>
+
+ <para>
+ Relation messages identify column types by their OIDs. In the case
+ of a built-in type, it is assumed that the client can look up that
+ type OID locally, so no additional data is needed. For a non-built-in
+ type OID, a Type message will be sent before the Relation message,
+ to provide the type name associated with that OID. Thus, a client that
+ needs to specifically identify the types of relation columns should
+ cache the contents of Type messages, and first consult that cache to
+ see if the type OID is defined there. If not, look up the type OID
+ locally.
+ </para>
+ </sect2>
+</sect1>
+
+<sect1 id="protocol-message-types">
+<title>Message Data Types</title>
+
+<para>
+This section describes the base data types used in messages.
+
+<variablelist>
+
+<varlistentry>
+<term>
+ Int<replaceable>n</replaceable>(<replaceable>i</replaceable>)
+</term>
+<listitem>
+<para>
+ An <replaceable>n</replaceable>-bit integer in network byte
+ order (most significant byte first).
+ If <replaceable>i</replaceable> is specified it
+ is the exact value that will appear, otherwise the value
+ is variable. Eg. Int16, Int32(42).
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Int<replaceable>n</replaceable>[<replaceable>k</replaceable>]
+</term>
+<listitem>
+<para>
+ An array of <replaceable>k</replaceable>
+ <replaceable>n</replaceable>-bit integers, each in network
+ byte order. The array length <replaceable>k</replaceable>
+ is always determined by an earlier field in the message.
+ Eg. Int16[M].
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ String(<replaceable>s</replaceable>)
+</term>
+<listitem>
+<para>
+ A null-terminated string (C-style string). There is no
+ specific length limitation on strings.
+ If <replaceable>s</replaceable> is specified it is the exact
+ value that will appear, otherwise the value is variable.
+ Eg. String, String("user").
+</para>
+
+<note>
+<para>
+<emphasis>There is no predefined limit</emphasis> on the length of a string
+that can be returned by the backend. Good coding strategy for a frontend
+is to use an expandable buffer so that anything that fits in memory can be
+accepted. If that's not feasible, read the full string and discard trailing
+characters that don't fit into your fixed-size buffer.
+</para>
+</note>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>(<replaceable>c</replaceable>)
+</term>
+<listitem>
+<para>
+ Exactly <replaceable>n</replaceable> bytes. If the field
+ width <replaceable>n</replaceable> is not a constant, it is
+ always determinable from an earlier field in the message.
+ If <replaceable>c</replaceable> is specified it is the exact
+ value. Eg. Byte2, Byte1('\n').
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</sect1>
+
+<sect1 id="protocol-message-formats">
+<title>Message Formats</title>
+
+<para>
+This section describes the detailed format of each message. Each is marked to
+indicate that it can be sent by a frontend (F), a backend (B), or both
+(F &amp; B).
+Notice that although each message includes a byte count at the beginning,
+the message format is defined so that the message end can be found without
+reference to the byte count. This aids validity checking. (The CopyData
+message is an exception, because it forms part of a data stream; the contents
+of any individual CopyData message cannot be interpretable on their own.)
+</para>
+
+<variablelist>
+
+
+<varlistentry>
+<term>
+AuthenticationOk (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(0)
+</term>
+<listitem>
+<para>
+ Specifies that the authentication was successful.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationKerberosV5 (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(2)
+</term>
+<listitem>
+<para>
+ Specifies that Kerberos V5 authentication is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationCleartextPassword (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(3)
+</term>
+<listitem>
+<para>
+ Specifies that a clear-text password is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationMD5Password (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(12)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(5)
+</term>
+<listitem>
+<para>
+ Specifies that an MD5-encrypted password is required.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte4
+</term>
+<listitem>
+<para>
+ The salt to use when encrypting the password.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationSCMCredential (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(6)
+</term>
+<listitem>
+<para>
+ Specifies that an SCM credentials message is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationGSS (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(7)
+</term>
+<listitem>
+<para>
+ Specifies that GSSAPI authentication is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationGSSContinue (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Specifies that this message contains GSSAPI or SSPI data.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ GSSAPI or SSPI authentication data.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationSSPI (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(9)
+</term>
+<listitem>
+<para>
+ Specifies that SSPI authentication is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationSASL (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(10)
+</term>
+<listitem>
+<para>
+ Specifies that SASL authentication is required.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+The message body is a list of SASL authentication mechanisms, in the
+server's order of preference. A zero byte is required as terminator after
+the last authentication mechanism name. For each mechanism, there is the
+following:
+<variablelist>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Name of a SASL authentication mechanism.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationSASLContinue (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(11)
+</term>
+<listitem>
+<para>
+ Specifies that this message contains a SASL challenge.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ SASL data, specific to the SASL mechanism being used.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+AuthenticationSASLFinal (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as an authentication request.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(12)
+</term>
+<listitem>
+<para>
+ Specifies that SASL authentication has completed.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ SASL outcome "additional data", specific to the SASL mechanism
+ being used.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+BackendKeyData (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('K')
+</term>
+<listitem>
+<para>
+ Identifies the message as cancellation key data.
+ The frontend must save these values if it wishes to be
+ able to issue CancelRequest messages later.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(12)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The process ID of this backend.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The secret key of this backend.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Bind (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('B')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Bind command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the destination portal
+ (an empty string selects the unnamed portal).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the source prepared statement
+ (an empty string selects the unnamed prepared statement).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of parameter format codes that follow
+ (denoted <replaceable>C</replaceable> below).
+ This can be zero to indicate that there are no parameters
+ or that the parameters all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all parameters; or it can equal the actual number of
+ parameters.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>C</replaceable>]
+</term>
+<listitem>
+<para>
+ The parameter format codes. Each must presently be
+ zero (text) or one (binary).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of parameter values that follow (possibly zero).
+ This must match the number of parameters needed by the query.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Next, the following pair of fields appear for each parameter:
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The length of the parameter value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL parameter value.
+ No value bytes follow in the NULL case.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The value of the parameter, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ After the last parameter, the following fields appear:
+<variablelist>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of result-column format codes that follow
+ (denoted <replaceable>R</replaceable> below).
+ This can be zero to indicate that there are no result columns
+ or that the result columns should all use the default format
+ (text);
+ or one, in which case the specified format code is applied
+ to all result columns (if any); or it can equal the actual
+ number of result columns of the query.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>R</replaceable>]
+</term>
+<listitem>
+<para>
+ The result-column format codes. Each must presently be
+ zero (text) or one (binary).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+BindComplete (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('2')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Bind-complete indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CancelRequest (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Int32(16)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(80877102)
+</term>
+<listitem>
+<para>
+ The cancel request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5678</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The process ID of the target backend.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The secret key for the target backend.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Close (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('C')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Close command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte1
+</term>
+<listitem>
+<para>
+ '<literal>S</literal>' to close a prepared statement; or
+ '<literal>P</literal>' to close a portal.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the prepared statement or portal to close
+ (an empty string selects the unnamed prepared statement
+ or portal).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CloseComplete (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('3')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Close-complete indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CommandComplete (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('C')
+</term>
+<listitem>
+<para>
+ Identifies the message as a command-completed response.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+ <para>
+ The command tag. This is usually a single
+ word that identifies which SQL command was completed.
+ </para>
+
+ <para>
+ For an <command>INSERT</command> command, the tag is
+ <literal>INSERT <replaceable>oid</replaceable>
+ <replaceable>rows</replaceable></literal>, where
+ <replaceable>rows</replaceable> is the number of rows
+ inserted. <replaceable>oid</replaceable> used to be the object ID
+ of the inserted row if <replaceable>rows</replaceable> was 1
+ and the target table had OIDs, but OIDs system columns are
+ not supported anymore; therefore <replaceable>oid</replaceable>
+ is always 0.
+ </para>
+
+ <para>
+ For a <command>DELETE</command> command, the tag is
+ <literal>DELETE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows deleted.
+ </para>
+
+ <para>
+ For an <command>UPDATE</command> command, the tag is
+ <literal>UPDATE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows updated.
+ </para>
+
+ <para>
+ For a <command>SELECT</command> or <command>CREATE TABLE AS</command>
+ command, the tag is <literal>SELECT <replaceable>rows</replaceable></literal>
+ where <replaceable>rows</replaceable> is the number of rows retrieved.
+ </para>
+
+ <para>
+ For a <command>MOVE</command> command, the tag is
+ <literal>MOVE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows the
+ cursor's position has been changed by.
+ </para>
+
+ <para>
+ For a <command>FETCH</command> command, the tag is
+ <literal>FETCH <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows that
+ have been retrieved from the cursor.
+ </para>
+
+ <para>
+ For a <command>COPY</command> command, the tag is
+ <literal>COPY <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows copied.
+ (Note: the row count appears only in
+ <productname>PostgreSQL</productname> 8.2 and later.)
+ </para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyData (F &amp; B)
+</term>
+<listitem>
+<para>
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('d')
+</term>
+<listitem>
+<para>
+ Identifies the message as <command>COPY</command> data.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ Data that forms part of a <command>COPY</command> data stream. Messages sent
+ from the backend will always correspond to single data rows,
+ but messages sent by frontends might divide the data stream
+ arbitrarily.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyDone (F &amp; B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('c')
+</term>
+<listitem>
+<para>
+ Identifies the message as a <command>COPY</command>-complete indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyFail (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('f')
+</term>
+<listitem>
+<para>
+ Identifies the message as a <command>COPY</command>-failure indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ An error message to report as the cause of failure.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyInResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('G')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Start Copy In response.
+ The frontend must now send copy-in data (if not
+ prepared to do so, send a CopyFail message).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ 0 indicates the overall <command>COPY</command> format is textual (rows
+ separated by newlines, columns separated by separator
+ characters, etc).
+ 1 indicates the overall copy format is binary (similar
+ to DataRow format).
+ See <xref linkend="sql-copy"/>
+ for more information.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</replaceable>]
+</term>
+<listitem>
+<para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyOutResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('H')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Start Copy Out response.
+ This message will be followed by copy-out data.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ 0 indicates the overall <command>COPY</command> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <xref linkend="sql-copy"/> for more information.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</replaceable>]
+</term>
+<listitem>
+<para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+CopyBothResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('W')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Start Copy Both response.
+ This message is used only for Streaming Replication.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ 0 indicates the overall <command>COPY</command> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <xref linkend="sql-copy"/> for more information.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</replaceable>]
+</term>
+<listitem>
+<para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+DataRow (B)
+</term>
+<listitem>
+<para>
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('D')
+</term>
+<listitem>
+<para>
+ Identifies the message as a data row.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of column values that follow (possibly zero).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Next, the following pair of fields appear for each column:
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The length of the column value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL column value.
+ No value bytes follow in the NULL case.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The value of the column, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Describe (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('D')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Describe command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte1
+</term>
+<listitem>
+<para>
+ '<literal>S</literal>' to describe a prepared statement; or
+ '<literal>P</literal>' to describe a portal.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the prepared statement or portal to describe
+ (an empty string selects the unnamed prepared statement
+ or portal).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+EmptyQueryResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('I')
+</term>
+<listitem>
+<para>
+ Identifies the message as a response to an empty query string.
+ (This substitutes for CommandComplete.)
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+ErrorResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('E')
+</term>
+<listitem>
+<para>
+ Identifies the message as an error.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+<variablelist>
+<varlistentry>
+<term>
+ Byte1
+</term>
+<listitem>
+<para>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <xref linkend="protocol-error-fields"/>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The field value.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Execute (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('E')
+</term>
+<listitem>
+<para>
+ Identifies the message as an Execute command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the portal to execute
+ (an empty string selects the unnamed portal).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Maximum number of rows to return, if portal contains
+ a query that returns rows (ignored otherwise). Zero
+ denotes <quote>no limit</quote>.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Flush (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('H')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Flush command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+FunctionCall (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('F')
+</term>
+<listitem>
+<para>
+ Identifies the message as a function call.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Specifies the object ID of the function to call.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of argument format codes that follow
+ (denoted <replaceable>C</replaceable> below).
+ This can be zero to indicate that there are no arguments
+ or that the arguments all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all arguments; or it can equal the actual number of
+ arguments.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>C</replaceable>]
+</term>
+<listitem>
+<para>
+ The argument format codes. Each must presently be
+ zero (text) or one (binary).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ Specifies the number of arguments being supplied to the
+ function.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Next, the following pair of fields appear for each argument:
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The length of the argument value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL argument value.
+ No value bytes follow in the NULL case.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The value of the argument, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ After the last argument, the following field appears:
+<variablelist>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The format code for the function result. Must presently be
+ zero (text) or one (binary).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+FunctionCallResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('V')
+</term>
+<listitem>
+<para>
+ Identifies the message as a function call result.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The length of the function result value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL function result.
+ No value bytes follow in the NULL case.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The value of the function result, in the format indicated by
+ the associated format code.
+ <replaceable>n</replaceable> is the above length.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+GSSENCRequest (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(80877104)
+</term>
+<listitem>
+<para>
+ The <acronym>GSSAPI</acronym> Encryption request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5680</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+GSSResponse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('p')
+</term>
+<listitem>
+<para>
+ Identifies the message as a GSSAPI or SSPI response. Note that
+ this is also used for SASL and password response messages.
+ The exact message type can be deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ GSSAPI/SSPI specific message data.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+NegotiateProtocolVersion (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('v')
+</term>
+<listitem>
+<para>
+ Identifies the message as a protocol version negotiation
+ message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Newest minor protocol version supported by the server
+ for the major protocol version requested by the client.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Number of protocol options not recognized by the server.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Then, for protocol option not recognized by the server, there
+ is the following:
+<variablelist>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The option name.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+NoData (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('n')
+</term>
+<listitem>
+<para>
+ Identifies the message as a no-data indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+NoticeResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('N')
+</term>
+<listitem>
+<para>
+ Identifies the message as a notice.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+<variablelist>
+<varlistentry>
+<term>
+ Byte1
+</term>
+<listitem>
+<para>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <xref linkend="protocol-error-fields"/>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The field value.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+NotificationResponse (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('A')
+</term>
+<listitem>
+<para>
+ Identifies the message as a notification response.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The process ID of the notifying backend process.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the channel that the notify has been raised on.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The <quote>payload</quote> string passed from the notifying process.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+ParameterDescription (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('t')
+</term>
+<listitem>
+<para>
+ Identifies the message as a parameter description.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of parameters used by the statement
+ (can be zero).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Then, for each parameter, there is the following:
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Specifies the object ID of the parameter data type.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+ParameterStatus (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('S')
+</term>
+<listitem>
+<para>
+ Identifies the message as a run-time parameter status report.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the run-time parameter being reported.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The current value of the parameter.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Parse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('P')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Parse command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The name of the destination prepared statement
+ (an empty string selects the unnamed prepared statement).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The query string to be parsed.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The number of parameter data types specified
+ (can be zero). Note that this is not an indication of
+ the number of parameters that might appear in the
+ query string, only the number that the frontend wants to
+ prespecify types for.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Then, for each parameter, there is the following:
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Specifies the object ID of the parameter data type.
+ Placing a zero here is equivalent to leaving the type
+ unspecified.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+ParseComplete (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('1')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Parse-complete indicator.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+PasswordMessage (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('p')
+</term>
+<listitem>
+<para>
+ Identifies the message as a password response. Note that
+ this is also used for GSSAPI, SSPI and SASL response messages.
+ The exact message type can be deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The password (encrypted, if requested).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+PortalSuspended (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('s')
+</term>
+<listitem>
+<para>
+ Identifies the message as a portal-suspended indicator.
+ Note this only appears if an Execute message's row-count limit
+ was reached.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Query (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('Q')
+</term>
+<listitem>
+<para>
+ Identifies the message as a simple query.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The query string itself.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+ReadyForQuery (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('Z')
+</term>
+<listitem>
+<para>
+ Identifies the message type. ReadyForQuery is sent
+ whenever the backend is ready for a new query cycle.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(5)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte1
+</term>
+<listitem>
+<para>
+ Current backend transaction status indicator.
+ Possible values are '<literal>I</literal>' if idle (not in
+ a transaction block); '<literal>T</literal>' if in a transaction
+ block; or '<literal>E</literal>' if in a failed transaction
+ block (queries will be rejected until block is ended).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+RowDescription (B)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('T')
+</term>
+<listitem>
+<para>
+ Identifies the message as a row description.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ Specifies the number of fields in a row (can be zero).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Then, for each field, there is the following:
+<variablelist>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The field name.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ If the field can be identified as a column of a specific
+ table, the object ID of the table; otherwise zero.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ If the field can be identified as a column of a specific
+ table, the attribute number of the column; otherwise zero.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The object ID of the field's data type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The data type size (see <varname>pg_type.typlen</varname>).
+ Note that negative values denote variable-width types.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ The type modifier (see <varname>pg_attribute.atttypmod</varname>).
+ The meaning of the modifier is type-specific.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ The format code being used for the field. Currently will
+ be zero (text) or one (binary). In a RowDescription
+ returned from the statement variant of Describe, the
+ format code is not yet known and will always be zero.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+SASLInitialResponse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('p')
+</term>
+<listitem>
+<para>
+ Identifies the message as an initial SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type is deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Name of the SASL authentication mechanism that the client
+ selected.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of SASL mechanism specific "Initial Client Response" that
+ follows, or -1 if there is no Initial Response.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ SASL mechanism specific "Initial Response".
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+SASLResponse (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('p')
+</term>
+<listitem>
+<para>
+ Identifies the message as a SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type can be deduced from the context.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ SASL mechanism specific message data.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+SSLRequest (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Int32(8)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(80877103)
+</term>
+<listitem>
+<para>
+ The <acronym>SSL</acronym> request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5679</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+StartupMessage (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(196608)
+</term>
+<listitem>
+<para>
+ The protocol version number. The most significant 16 bits are
+ the major version number (3 for the protocol described here).
+ The least significant 16 bits are the minor version number
+ (0 for the protocol described here).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ The protocol version number is followed by one or more pairs of
+ parameter name and value strings. A zero byte is required as a
+ terminator after the last name/value pair.
+ Parameters can appear in any
+ order. <literal>user</literal> is required, others are optional.
+ Each parameter is specified as:
+<variablelist>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The parameter name. Currently recognized names are:
+
+<variablelist>
+<varlistentry>
+<term>
+ <literal>user</literal>
+</term>
+<listitem>
+<para>
+ The database user name to connect as. Required;
+ there is no default.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ <literal>database</literal>
+</term>
+<listitem>
+<para>
+ The database to connect to. Defaults to the user name.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ <literal>options</literal>
+</term>
+<listitem>
+<para>
+ Command-line arguments for the backend. (This is
+ deprecated in favor of setting individual run-time
+ parameters.) Spaces within this string are
+ considered to separate arguments, unless escaped with
+ a backslash (<literal>\</literal>); write <literal>\\</literal> to
+ represent a literal backslash.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ <literal>replication</literal>
+</term>
+<listitem>
+<para>
+ Used to connect in streaming replication mode, where
+ a small set of replication commands can be issued
+ instead of SQL statements. Value can be
+ <literal>true</literal>, <literal>false</literal>, or
+ <literal>database</literal>, and the default is
+ <literal>false</literal>. See
+ <xref linkend="protocol-replication"/> for details.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+ In addition to the above, other parameters may be listed.
+ Parameter names beginning with <literal>_pq_.</literal> are
+ reserved for use as protocol extensions, while others are
+ treated as run-time parameters to be set at backend start
+ time. Such settings will be applied during backend start
+ (after parsing the command-line arguments if any) and will
+ act as session defaults.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The parameter value.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Sync (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('S')
+</term>
+<listitem>
+<para>
+ Identifies the message as a Sync command.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
+<term>
+Terminate (F)
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('X')
+</term>
+<listitem>
+<para>
+ Identifies the message as a termination.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32(4)
+</term>
+<listitem>
+<para>
+ Length of message contents in bytes, including self.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</para>
+</listitem>
+</varlistentry>
+
+
+</variablelist>
+
+</sect1>
+
+
+<sect1 id="protocol-error-fields">
+<title>Error and Notice Message Fields</title>
+
+<para>
+This section describes the fields that can appear in ErrorResponse and
+NoticeResponse messages. Each field type has a single-byte identification
+token. Note that any given field type should appear at most once per
+message.
+</para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+<literal>S</literal>
+</term>
+<listitem>
+<para>
+ Severity: the field contents are
+ <literal>ERROR</literal>, <literal>FATAL</literal>, or
+ <literal>PANIC</literal> (in an error message), or
+ <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message),
+ or a localized translation of one of these. Always present.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>V</literal>
+</term>
+<listitem>
+<para>
+ Severity: the field contents are
+ <literal>ERROR</literal>, <literal>FATAL</literal>, or
+ <literal>PANIC</literal> (in an error message), or
+ <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message).
+ This is identical to the <literal>S</literal> field except
+ that the contents are never localized. This is present only in
+ messages generated by <productname>PostgreSQL</productname> versions 9.6
+ and later.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>C</literal>
+</term>
+<listitem>
+<para>
+ Code: the SQLSTATE code for the error (see <xref
+ linkend="errcodes-appendix"/>). Not localizable. Always present.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>M</literal>
+</term>
+<listitem>
+<para>
+ Message: the primary human-readable error message.
+ This should be accurate but terse (typically one line).
+ Always present.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>D</literal>
+</term>
+<listitem>
+<para>
+ Detail: an optional secondary error message carrying more
+ detail about the problem. Might run to multiple lines.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>H</literal>
+</term>
+<listitem>
+<para>
+ Hint: an optional suggestion what to do about the problem.
+ This is intended to differ from Detail in that it offers advice
+ (potentially inappropriate) rather than hard facts.
+ Might run to multiple lines.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>P</literal>
+</term>
+<listitem>
+<para>
+ Position: the field value is a decimal ASCII integer, indicating
+ an error cursor position as an index into the original query string.
+ The first character has index 1, and positions are measured in
+ characters not bytes.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>p</literal>
+</term>
+<listitem>
+<para>
+ Internal position: this is defined the same as the <literal>P</literal>
+ field, but it is used when the cursor position refers to an internally
+ generated command rather than the one submitted by the client.
+ The <literal>q</literal> field will always appear when this field appears.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>q</literal>
+</term>
+<listitem>
+<para>
+ Internal query: the text of a failed internally-generated command.
+ This could be, for example, an SQL query issued by a PL/pgSQL function.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>W</literal>
+</term>
+<listitem>
+<para>
+ Where: an indication of the context in which the error occurred.
+ Presently this includes a call stack traceback of active
+ procedural language functions and internally-generated queries.
+ The trace is one entry per line, most recent first.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>s</literal>
+</term>
+<listitem>
+<para>
+ Schema name: if the error was associated with a specific database
+ object, the name of the schema containing that object, if any.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>t</literal>
+</term>
+<listitem>
+<para>
+ Table name: if the error was associated with a specific table, the
+ name of the table. (Refer to the schema name field for the name of
+ the table's schema.)
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>c</literal>
+</term>
+<listitem>
+<para>
+ Column name: if the error was associated with a specific table column,
+ the name of the column. (Refer to the schema and table name fields to
+ identify the table.)
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>d</literal>
+</term>
+<listitem>
+<para>
+ Data type name: if the error was associated with a specific data type,
+ the name of the data type. (Refer to the schema name field for the
+ name of the data type's schema.)
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>n</literal>
+</term>
+<listitem>
+<para>
+ Constraint name: if the error was associated with a specific
+ constraint, the name of the constraint. Refer to fields listed above
+ for the associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with constraint
+ syntax.)
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>F</literal>
+</term>
+<listitem>
+<para>
+ File: the file name of the source-code location where the error
+ was reported.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>L</literal>
+</term>
+<listitem>
+<para>
+ Line: the line number of the source-code location where the error
+ was reported.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>R</literal>
+</term>
+<listitem>
+<para>
+ Routine: the name of the source-code routine reporting the error.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<note>
+ <para>
+ The fields for schema name, table name, column name, data type name, and
+ constraint name are supplied only for a limited number of error types;
+ see <xref linkend="errcodes-appendix"/>. Frontends should not assume that
+ the presence of any of these fields guarantees the presence of another
+ field. Core error sources observe the interrelationships noted above, but
+ user-defined functions may use these fields in other ways. In the same
+ vein, clients should not assume that these fields denote contemporary
+ objects in the current database.
+ </para>
+</note>
+
+<para>
+The client is responsible for formatting displayed information to meet its
+needs; in particular it should break long lines as needed. Newline characters
+appearing in the error message fields should be treated as paragraph breaks,
+not line breaks.
+</para>
+
+</sect1>
+
+<sect1 id="protocol-logicalrep-message-formats">
+<title>Logical Replication Message Formats</title>
+
+<para>
+This section describes the detailed format of each logical replication message.
+These messages are returned either by the replication slot SQL interface or are
+sent by a walsender. In case of a walsender they are encapsulated inside the replication
+protocol WAL messages as described in <xref linkend="protocol-replication"/>
+and generally obey same message flow as physical replication.
+</para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+Begin
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('B')
+</term>
+<listitem>
+<para>
+ Identifies the message as a begin message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The final LSN of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Message
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('M')
+</term>
+<listitem>
+<para>
+ Identifies the message as a logical decoding message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Flags; Either 0 for no flags or 1 if the logical decoding
+ message is transactional.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The LSN of the logical decoding message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ The prefix of the logical decoding message.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of the content.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The content of the logical decoding message.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Commit
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('C')
+</term>
+<listitem>
+<para>
+ Identifies the message as a commit message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Flags; currently unused (must be 0).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The LSN of the commit.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The end LSN of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Origin
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('O')
+</term>
+<listitem>
+<para>
+ Identifies the message as an origin message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The LSN of the commit on the origin server.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Name of the origin.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+
+<para>
+ Note that there can be multiple Origin messages inside a single transaction.
+</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Relation
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('R')
+</term>
+<listitem>
+<para>
+ Identifies the message as a relation message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the relation.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Namespace (empty string for <literal>pg_catalog</literal>).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Relation name.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Replica identity setting for the relation (same as
+ <structfield>relreplident</structfield> in <structname>pg_class</structname>).
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ Number of columns.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Next, the following message part appears for each column (except generated columns):
+<variablelist>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Flags for the column. Currently can be either 0 for no flags
+ or 1 which marks the column as part of the key.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Name of the column.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the column's data type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Type modifier of the column (<structfield>atttypmod</structfield>).
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Type
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('Y')
+</term>
+<listitem>
+<para>
+ Identifies the message as a type message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the data type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Namespace (empty string for <literal>pg_catalog</literal>).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ String
+</term>
+<listitem>
+<para>
+ Name of the data type.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Insert
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('I')
+</term>
+<listitem>
+<para>
+ Identifies the message as an insert message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the relation corresponding to the ID in the relation
+ message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte1('N')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData message as a new tuple.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ TupleData
+</term>
+<listitem>
+<para>
+ TupleData message part representing the contents of new tuple.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Update
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('U')
+</term>
+<listitem>
+<para>
+ Identifies the message as an update message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the relation corresponding to the ID in the relation
+ message.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte1('K')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData submessage as a key.
+ This field is optional and is only present if
+ the update changed data in any of the column(s) that are
+ part of the REPLICA IDENTITY index.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte1('O')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData submessage as an old tuple.
+ This field is optional and is only present if table in which
+ the update happened has REPLICA IDENTITY set to FULL.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ TupleData
+</term>
+<listitem>
+<para>
+ TupleData message part representing the contents of the old tuple
+ or primary key. Only present if the previous 'O' or 'K' part
+ is present.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte1('N')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData message as a new tuple.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ TupleData
+</term>
+<listitem>
+<para>
+ TupleData message part representing the contents of a new tuple.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+
+<para>
+ The Update message may contain either a 'K' message part or an 'O' message part
+ or neither of them, but never both of them.
+</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Delete
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('D')
+</term>
+<listitem>
+<para>
+ Identifies the message as a delete message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the relation corresponding to the ID in the relation
+ message.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte1('K')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData submessage as a key.
+ This field is present if the table in which the delete has
+ happened uses an index as REPLICA IDENTITY.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ Byte1('O')
+</term>
+<listitem>
+<para>
+ Identifies the following TupleData message as an old tuple.
+ This field is present if the table in which the delete
+ happened has REPLICA IDENTITY set to FULL.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+ TupleData
+</term>
+<listitem>
+<para>
+ TupleData message part representing the contents of the old tuple
+ or primary key, depending on the previous field.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+ The Delete message may contain either a 'K' message part or an 'O' message part,
+ but never both of them.
+</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Truncate
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('T')
+</term>
+<listitem>
+<para>
+ Identifies the message as a truncate message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Number of relations
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Option bits for <command>TRUNCATE</command>:
+ 1 for <literal>CASCADE</literal>, 2 for <literal>RESTART IDENTITY</literal>
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ ID of the relation corresponding to the ID in the relation
+ message. This field is repeated for each relation.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>
+
+The following messages (Stream Start, Stream Stop, Stream Commit, and
+Stream Abort) are available since protocol version 2.
+
+</para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+Stream Start
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('S')
+</term>
+<listitem>
+<para>
+ Identifies the message as a stream start message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ A value of 1 indicates this is the first stream segment for
+ this XID, 0 for any other stream segment.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Stream Stop
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('E')
+</term>
+<listitem>
+<para>
+ Identifies the message as a stream stop message.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Stream Commit
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('c')
+</term>
+<listitem>
+<para>
+ Identifies the message as a stream commit message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int8
+</term>
+<listitem>
+<para>
+ Flags; currently unused (must be 0).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The LSN of the commit.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ The end LSN of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int64
+</term>
+<listitem>
+<para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+Stream Abort
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('A')
+</term>
+<listitem>
+<para>
+ Identifies the message as a stream abort message.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the transaction.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Xid of the subtransaction (will be same as xid of the transaction for top-level
+ transactions).
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<para>
+
+The following message parts are shared by the above messages.
+
+</para>
+
+<variablelist>
+
+<varlistentry>
+<term>
+TupleData
+</term>
+<listitem>
+<para>
+
+<variablelist>
+<varlistentry>
+<term>
+ Int16
+</term>
+<listitem>
+<para>
+ Number of columns.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Next, one of the following submessages appears for each column (except generated columns):
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('n')
+</term>
+<listitem>
+<para>
+ Identifies the data as NULL value.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Or
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('u')
+</term>
+<listitem>
+<para>
+ Identifies unchanged TOASTed value (the actual value is not
+ sent).
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Or
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('t')
+</term>
+<listitem>
+<para>
+ Identifies the data as text formatted value.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+ Or
+<variablelist>
+<varlistentry>
+<term>
+ Byte1('b')
+</term>
+<listitem>
+<para>
+ Identifies the data as binary formatted value.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int32
+</term>
+<listitem>
+<para>
+ Length of the column value.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Byte<replaceable>n</replaceable>
+</term>
+<listitem>
+<para>
+ The value of the column, either in binary or in text format.
+ (As specified in the preceding format byte).
+ <replaceable>n</replaceable> is the above length.
+
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+</sect1>
+
+<sect1 id="protocol-changes">
+<title>Summary of Changes since Protocol 2.0</title>
+
+<para>
+This section provides a quick checklist of changes, for the benefit of
+developers trying to update existing client libraries to protocol 3.0.
+</para>
+
+<para>
+The initial startup packet uses a flexible list-of-strings format
+instead of a fixed format. Notice that session default values for run-time
+parameters can now be specified directly in the startup packet. (Actually,
+you could do that before using the <literal>options</literal> field, but given the
+limited width of <literal>options</literal> and the lack of any way to quote
+whitespace in the values, it wasn't a very safe technique.)
+</para>
+
+<para>
+All messages now have a length count immediately following the message type
+byte (except for startup packets, which have no type byte). Also note that
+PasswordMessage now has a type byte.
+</para>
+
+<para>
+ErrorResponse and NoticeResponse ('<literal>E</literal>' and '<literal>N</literal>')
+messages now contain multiple fields, from which the client code can
+assemble an error message of the desired level of verbosity. Note that
+individual fields will typically not end with a newline, whereas the single
+string sent in the older protocol always did.
+</para>
+
+<para>
+The ReadyForQuery ('<literal>Z</literal>') message includes a transaction status
+indicator.
+</para>
+
+<para>
+The distinction between BinaryRow and DataRow message types is gone; the
+single DataRow message type serves for returning data in all formats.
+Note that the layout of DataRow has changed to make it easier to parse.
+Also, the representation of binary values has changed: it is no longer
+directly tied to the server's internal representation.
+</para>
+
+<para>
+There is a new <quote>extended query</quote> sub-protocol, which adds the frontend
+message types Parse, Bind, Execute, Describe, Close, Flush, and Sync, and the
+backend message types ParseComplete, BindComplete, PortalSuspended,
+ParameterDescription, NoData, and CloseComplete. Existing clients do not
+have to concern themselves with this sub-protocol, but making use of it
+might allow improvements in performance or functionality.
+</para>
+
+<para>
+<command>COPY</command> data is now encapsulated into CopyData and CopyDone messages. There
+is a well-defined way to recover from errors during <command>COPY</command>. The special
+<quote><literal>\.</literal></quote> last line is not needed anymore, and is not sent
+during <command>COPY OUT</command>.
+(It is still recognized as a terminator during <command>COPY IN</command>, but its use is
+deprecated and will eventually be removed.) Binary <command>COPY</command> is supported.
+The CopyInResponse and CopyOutResponse messages include fields indicating
+the number of columns and the format of each column.
+</para>
+
+<para>
+The layout of FunctionCall and FunctionCallResponse messages has changed.
+FunctionCall can now support passing NULL arguments to functions. It also
+can handle passing parameters and retrieving results in either text or
+binary format. There is no longer any reason to consider FunctionCall a
+potential security hole, since it does not offer direct access to internal
+server data representations.
+</para>
+
+<para>
+The backend sends ParameterStatus ('<literal>S</literal>') messages during connection
+startup for all parameters it considers interesting to the client library.
+Subsequently, a ParameterStatus message is sent whenever the active value
+changes for any of these parameters.
+</para>
+
+<para>
+The RowDescription ('<literal>T</literal>') message carries new table OID and column
+number fields for each column of the described row. It also shows the format
+code for each column.
+</para>
+
+<para>
+The CursorResponse ('<literal>P</literal>') message is no longer generated by
+the backend.
+</para>
+
+<para>
+The NotificationResponse ('<literal>A</literal>') message has an additional string
+field, which can carry a <quote>payload</quote> string passed
+from the <command>NOTIFY</command> event sender.
+</para>
+
+<para>
+The EmptyQueryResponse ('<literal>I</literal>') message used to include an empty
+string parameter; this has been removed.
+</para>
+
+</sect1>
+
+</chapter>