diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
commit | 293913568e6a7a86fd1479e1cff8e2ecb58d6568 (patch) | |
tree | fc3b469a3ec5ab71b36ea97cc7aaddb838423a0c /doc/src/sgml/protocol.sgml | |
parent | Initial commit. (diff) | |
download | postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.tar.xz postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.zip |
Adding upstream version 16.2.upstream/16.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/src/sgml/protocol.sgml')
-rw-r--r-- | doc/src/sgml/protocol.sgml | 7515 |
1 files changed, 7515 insertions, 0 deletions
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml new file mode 100644 index 0000000..5dff071 --- /dev/null +++ b/doc/src/sgml/protocol.sgml @@ -0,0 +1,7515 @@ +<!-- 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 id="protocol-flow-start-up"> + <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>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 id="protocol-flow-simple-query"> + <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 — 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 fail unless it is the first + command in the pipeline. Furthermore, upon success it will force an + immediate commit to preserve database consistency. Thus a Sync + immediately following one of these commands 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 be skipped and thus not + produce a completion message. + </para> + </sect2> + + <sect2 id="protocol-flow-function-call"> + <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 — 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 id="protocol-flow-canceling-requests"> + <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 — 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 id="protocol-flow-termination"> + <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 id="protocol-flow-ssl"> + <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 id="protocol-flow-gssapi"> + <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 id="protocol-replication-identify-system"> + <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> + + <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>int8</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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-show"> + <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 id="protocol-replication-timeline-history"> + <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> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-create-replication-slot" xreflabel="CREATE_REPLICATION_SLOT"> + <term><literal>CREATE_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> [ <literal>TEMPORARY</literal> ] { <literal>PHYSICAL</literal> | <literal>LOGICAL</literal> <replaceable class="parameter">output_plugin</replaceable> } [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] + <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> + </variablelist> + + <para>The following options are supported:</para> + + <variablelist> + <varlistentry> + <term><literal>TWO_PHASE [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If true, this logical replication slot supports decoding of two-phase + commit. With this option, commands related to two-phase commit such as + <literal>PREPARE TRANSACTION</literal>, <literal>COMMIT PREPARED</literal> + and <literal>ROLLBACK PREPARED</literal> are decoded and transmitted. + The transaction will be decoded and transmitted at + <literal>PREPARE TRANSACTION</literal> time. + The default is false. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>RESERVE_WAL [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If true, this physical replication slot reserves <acronym>WAL</acronym> + immediately. Otherwise, <acronym>WAL</acronym> is only reserved upon + connection from a streaming replication client. + The default is false. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>SNAPSHOT { 'export' | 'use' | 'nothing' }</literal></term> + <listitem> + <para> + Decides what to do with the snapshot created during logical slot + initialization. <literal>'export'</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'</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>'nothing'</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 id="protocol-replication-create-replication-slot-legacy"> + <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> | <literal>TWO_PHASE</literal> ] } + </term> + <listitem> + <para> + For compatibility with older releases, this alternative syntax for + the <literal>CREATE_REPLICATION_SLOT</literal> command is still supported. + </para> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-read-replication-slot"> + <term><literal>READ_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> + <indexterm><primary>READ_REPLICATION_SLOT</primary></indexterm> + </term> + <listitem> + <para> + Read some information associated with a replication slot. Returns a tuple + with <literal>NULL</literal> values if the replication slot does not + exist. This command is currently only supported for physical replication + slots. + </para> + + <para> + In response to this command, the server will return a one-row result set, + containing the following fields: + <variablelist> + <varlistentry> + <term><literal>slot_type</literal> (<type>text</type>)</term> + <listitem> + <para> + The replication slot's type, either <literal>physical</literal> or + <literal>NULL</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>restart_lsn</literal> (<type>text</type>)</term> + <listitem> + <para> + The replication slot's <literal>restart_lsn</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>restart_tli</literal> (<type>int8</type>)</term> + <listitem> + <para> + The timeline ID associated with <literal>restart_lsn</literal>, + following the current timeline history. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-start-replication"> + <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> + + <variablelist> + <varlistentry id="protocol-replication-xlogdata"> + <term>XLogData (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-primary-keepalive-message"> + <term>Primary keepalive message (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + </variablelist> + + <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> + + <variablelist> + <varlistentry id="protocol-replication-standby-status-update"> + <term>Standby status update (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-hot-standby-feedback-message"> + <term>Hot standby feedback message (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-replication-start-replication-slot-logical"> + <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 either WAL location <replaceable + class="parameter">XXX/XXX</replaceable> or the slot's + <literal>confirmed_flush_lsn</literal> (see <xref + linkend="view-pg-replication-slots"/>), whichever is greater. This + behavior makes it easier for clients to avoid updating their local LSN + status when there is no data to process. However, starting at a + different LSN than requested might not catch certain kinds of client + errors; so the client may wish to check that + <literal>confirmed_flush_lsn</literal> matches its expectations before + issuing <literal>START_REPLICATION</literal>. + </para> + + <para> + The server can reply with an error, for example if the + slot does not exist. On success, the 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 output + plugin. See <xref linkend="protocol-logical-replication"/> for + options that are accepted by the standard (<literal>pgoutput</literal>) + 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 id="protocol-replication-drop-replication-slot"> + <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> [ ( <replaceable class="parameter">option</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>TARGET</literal> <replaceable>'target'</replaceable></term> + <listitem> + <para> + Tells the server where to send the backup. If the target is + <literal>client</literal>, which is the default, the backup data is + sent to the client. If it is <literal>server</literal>, the backup + data is written to the server at the pathname specified by the + <literal>TARGET_DETAIL</literal> option. If it is + <literal>blackhole</literal>, the backup data is not sent + anywhere; it is simply discarded. + </para> + + <para> + The <literal>server</literal> target requires superuser privilege or + being granted the <literal>pg_write_server_files</literal> role. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>TARGET_DETAIL</literal> <replaceable>'detail'</replaceable></term> + <listitem> + <para> + Provides additional information about the backup target. + </para> + + <para> + Currently, this option can only be used when the backup target is + <literal>server</literal>. It specifies the server directory + to which the backup should be written. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>PROGRESS [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If set to true, 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. + The default is false. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>CHECKPOINT { 'fast' | 'spread' }</literal></term> + <listitem> + <para> + Sets the type of checkpoint to be performed at the beginning of the + base backup. The default is <literal>spread</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>WAL [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If set to true, 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. The default is false. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>WAIT [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If set to true, the backup will wait until the last required WAL + segment has been archived, or emit a warning if WAL archiving is + not enabled. If false, the backup will neither wait nor warn, + leaving the client responsible for ensuring the required log is + available. The default is true. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>COMPRESSION</literal> <replaceable>'method'</replaceable></term> + <listitem> + <para> + Instructs the server to compress the backup using the specified + method. Currently, the supported methods are <literal>gzip</literal>, + <literal>lz4</literal>, and <literal>zstd</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>COMPRESSION_DETAIL</literal> <replaceable>detail</replaceable></term> + <listitem> + <para> + Specifies details for the chosen compression method. This should only + be used in conjunction with the <literal>COMPRESSION</literal> + option. If the value is an integer, it specifies the compression + level. Otherwise, it should be a comma-separated list of items, + each of the form <replaceable>keyword</replaceable> or + <replaceable>keyword=value</replaceable>. Currently, the supported + keywords are <literal>level</literal>, <literal>long</literal> and + <literal>workers</literal>. + </para> + + <para> + The <literal>level</literal> keyword sets the compression level. + For <literal>gzip</literal> the compression level should be an + integer between <literal>1</literal> and <literal>9</literal> + (default <literal>Z_DEFAULT_COMPRESSION</literal> or + <literal>-1</literal>), for <literal>lz4</literal> an integer + between 1 and 12 (default <literal>0</literal> for fast compression + mode), and for <literal>zstd</literal> an integer between + <literal>ZSTD_minCLevel()</literal> (usually <literal>-131072</literal>) + and <literal>ZSTD_maxCLevel()</literal> (usually <literal>22</literal>), + (default <literal>ZSTD_CLEVEL_DEFAULT</literal> or + <literal>3</literal>). + </para> + + <para> + The <literal>long</literal> keyword enables long-distance matching + mode, for improved compression ratio, at the expense of higher memory + use. Long-distance mode is supported only for + <literal>zstd</literal>. + </para> + + <para> + The <literal>workers</literal> keyword sets the number of threads + that should be used for parallel compression. Parallel compression + is supported only for <literal>zstd</literal>. + </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 [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If true, 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. + The default is false. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>VERIFY_CHECKSUMS [ <replaceable class="parameter">boolean</replaceable> ]</literal></term> + <listitem> + <para> + If true, checksums are verified during a base backup if they are + enabled. If false, this is skipped. The default is true. + </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, a CopyOutResponse will be sent. + The payload of each CopyData message will contain a message in one of + the following formats: + </para> + + <variablelist> + <varlistentry> + <term>new archive (B)</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('n')</term> + <listitem><para> + Identifies the message as indicating the start of a new archive. + There will be one archive for the main data directory and one + for each additional tablespace; each will use tar format + (following the <quote>ustar interchange format</quote> specified + in the POSIX 1003.1-2008 standard). + </para></listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem><para> + The file name for this archive. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem><para> + For the main data directory, an empty string. For other + tablespaces, the full path to the directory from which this + archive was created. + </para></listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry> + <term>manifest (B)</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('m')</term> + <listitem><para> + Identifies the message as indicating the start of the backup + manifest. + </para></listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry> + <term>archive or manifest data (B)</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('d')</term> + <listitem><para> + Identifies the message as containing archive or manifest data. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>Byte<replaceable>n</replaceable></term> + <listitem><para> + Data bytes. + </para></listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry> + <term>progress report (B)</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('p')</term> + <listitem><para> + Identifies the message as a progress report. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>Int64</term> + <listitem><para> + The number of bytes from the current tablespace for which + processing has been completed. + </para></listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + </variablelist> + + <para> + After the CopyOutResponse, or all such responses, have been sent, 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> + + <para> + <productname>PostgreSQL</productname> logical decoding supports output + plugins. <literal>pgoutput</literal> is the standard one used for + the built-in logical replication. + </para> + + <sect2 id="protocol-logical-replication-params"> + <title>Logical Streaming Replication Parameters</title> + + <para> + Using the <literal>START_REPLICATION</literal> command, + <literal>pgoutput</literal> accepts the following options: + + <variablelist> + <varlistentry> + <term> + proto_version + </term> + <listitem> + <para> + Protocol version. Currently versions <literal>1</literal>, <literal>2</literal>, + <literal>3</literal>, and <literal>4</literal> are supported. A valid + version is required. + </para> + <para> + Version <literal>2</literal> is supported only for server version 14 + and above, and it allows streaming of large in-progress transactions. + </para> + <para> + Version <literal>3</literal> is supported only for server version 15 + and above, and it allows streaming of two-phase commits. + </para> + <para> + Version <literal>4</literal> is supported only for server version 16 + and above, and it allows streams of large in-progress transactions to + be applied in parallel. + </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. + At least one publication name is required. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + binary + </term> + <listitem> + <para> + Boolean option to use binary transfer mode. Binary mode is faster + than the text mode but slightly less robust. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + messages + </term> + <listitem> + <para> + Boolean option to enable sending the messages that are written + by <function>pg_logical_emit_message</function>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + streaming + </term> + <listitem> + <para> + Boolean option to enable streaming of in-progress transactions. + It accepts an additional value "parallel" to enable sending extra + information with some messages to be used for parallelisation. + Minimum protocol version 2 is required to turn it on. Minimum protocol + version 4 is required for the "parallel" option. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + two_phase + </term> + <listitem> + <para> + Boolean option to enable two-phase transactions. Minimum protocol + version 3 is required to turn it on. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + origin + </term> + <listitem> + <para> + Option to send changes by their origin. Possible values are "none" + to only send the changes that have no origin associated, or "any" + to send the changes regardless of their origin. This can be used + to avoid loops (infinite replication of the same data) among + replication nodes. + </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. Similarly, all messages between a pair of + Begin Prepare and Prepare 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 a 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. + </para> + + <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> + </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 & 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 id="protocol-message-formats-AuthenticationOk"> + <term>AuthenticationOk (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationKerberosV5"> + <term>AuthenticationKerberosV5 (B)</term> + <listitem> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationCleartextPassword"> + <term>AuthenticationCleartextPassword (B)</term> + <listitem> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationMD5Password"> + <term>AuthenticationMD5Password (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationGSS"> + <term>AuthenticationGSS (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationGSSContinue"> + <term>AuthenticationGSSContinue (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationSSPI"> + <term>AuthenticationSSPI (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationSASL"> + <term>AuthenticationSASL (B)</term> + <listitem> + <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> + + <para> + 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 id="protocol-message-formats-AuthenticationSASLContinue"> + <term>AuthenticationSASLContinue (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-AuthenticationSASLFinal"> + <term>AuthenticationSASLFinal (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-BackendKeyData"> + <term>BackendKeyData (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Bind"> + <term>Bind (F)</term> + <listitem> + <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> + + <para> + Next, the following pair of fields appear for each parameter: + </para> + + <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> + + <para> + After the last parameter, the following fields appear: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-BindComplete"> + <term>BindComplete (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CancelRequest"> + <term>CancelRequest (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Close"> + <term>Close (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CloseComplete"> + <term>CloseComplete (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CommandComplete"> + <term>CommandComplete (B)</term> + <listitem> + <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>MERGE</command> command, the tag is + <literal>MERGE <replaceable>rows</replaceable></literal> where + <replaceable>rows</replaceable> is the number of rows inserted, + updated, or deleted. + </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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyData"> + <term>CopyData (F & B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyDone"> + <term>CopyDone (F & B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyFail"> + <term>CopyFail (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyInResponse"> + <term>CopyInResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyOutResponse"> + <term>CopyOutResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-CopyBothResponse"> + <term>CopyBothResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-DataRow"> + <term>DataRow (B)</term> + <listitem> + <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> + + <para> + Next, the following pair of fields appear for each column: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Describe"> + <term>Describe (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-EmptyQueryResponse"> + <term>EmptyQueryResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-ErrorResponse"> + <term>ErrorResponse (B)</term> + <listitem> + <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> + + <para> + 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: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Execute"> + <term>Execute (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Flush"> + <term>Flush (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-FunctionCall"> + <term>FunctionCall (F)</term> + <listitem> + <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> + + <para> + Next, the following pair of fields appear for each argument: + </para> + + <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> + + <para> + After the last argument, the following field appears: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-FunctionCallResponse"> + <term>FunctionCallResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-GSSENCRequest"> + <term>GSSENCRequest (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-GSSResponse"> + <term>GSSResponse (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-NegotiateProtocolVersion"> + <term>NegotiateProtocolVersion (B)</term> + <listitem> + <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> + + <para> + Then, for protocol option not recognized by the server, there + is the following: + </para> + + <variablelist> + <varlistentry> + <term>String</term> + <listitem> + <para> + The option name. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-NoData"> + <term>NoData (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-NoticeResponse"> + <term>NoticeResponse (B)</term> + <listitem> + <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> + + <para> + 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: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-NotificationResponse"> + <term>NotificationResponse (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-ParameterDescription"> + <term>ParameterDescription (B)</term> + <listitem> + <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> + + <para> + Then, for each parameter, there is the following: + </para> + + <variablelist> + <varlistentry> + <term>Int32</term> + <listitem> + <para> + Specifies the object ID of the parameter data type. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-ParameterStatus"> + <term>ParameterStatus (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Parse"> + <term>Parse (F)</term> + <listitem> + <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> + + <para> + Then, for each parameter, there is the following: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-ParseComplete"> + <term>ParseComplete (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-PasswordMessage"> + <term>PasswordMessage (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-PortalSuspended"> + <term>PortalSuspended (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Query"> + <term>Query (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-ReadyForQuery"> + <term>ReadyForQuery (B)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-RowDescription"> + <term>RowDescription (B)</term> + <listitem> + <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> + + <para> + Then, for each field, there is the following: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-SASLInitialResponse"> + <term>SASLInitialResponse (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-SASLResponse"> + <term>SASLResponse (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-SSLRequest"> + <term>SSLRequest (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-StartupMessage"> + <term>StartupMessage (F)</term> + <listitem> + <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> + + <para> + 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: + </para> + + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Sync"> + <term>Sync (F)</term> + <listitem> + <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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-message-formats-Terminate"> + <term>Terminate (F)</term> + <listitem> + <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> + </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 either returned by the replication slot SQL + interface or are sent by a walsender. In the case of a walsender, they are + encapsulated inside replication protocol WAL messages as described in + <xref linkend="protocol-replication"/>, and generally obey the same message + flow as physical replication. + </para> + + <variablelist> + <varlistentry id="protocol-logicalrep-message-formats-Begin"> + <term>Begin</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('B')</term> + <listitem> + <para> + Identifies the message as a begin message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The final LSN of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</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 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Message"> + <term>Message</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('M')</term> + <listitem> + <para> + Identifies the message as a logical decoding message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (XLogRecPtr)</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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Commit"> + <term>Commit</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('C')</term> + <listitem> + <para> + Identifies the message as a commit message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the commit. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Origin"> + <term>Origin</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('O')</term> + <listitem> + <para> + Identifies the message as an origin message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</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> + Note that there can be multiple Origin messages inside a single transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Relation"> + <term>Relation</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('R')</term> + <listitem> + <para> + Identifies the message as a relation message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID 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> + + <para> + Next, the following message part appears for each column included in + the publication (except generated columns): + </para> + + <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 (Oid)</term> + <listitem> + <para> + OID 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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Type"> + <term>Type</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('Y')</term> + <listitem> + <para> + Identifies the message as a type message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID 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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Insert"> + <term>Insert</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('I')</term> + <listitem> + <para> + Identifies the message as an insert message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID 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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Update"> + <term>Update</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('U')</term> + <listitem> + <para> + Identifies the message as an update message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID 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> + 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 id="protocol-logicalrep-message-formats-Delete"> + <term>Delete</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('D')</term> + <listitem> + <para> + Identifies the message as a delete message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID 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> + The Delete message may contain either a 'K' message part or an 'O' message part, + but never both of them. + </para> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Truncate"> + <term>Truncate</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('T')</term> + <listitem> + <para> + Identifies the message as a truncate message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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 (Oid)</term> + <listitem> + <para> + OID of the relation corresponding to the ID in the relation + message. This field is repeated for each relation. + </para> + </listitem> + </varlistentry> + </variablelist> + </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 id="protocol-logicalrep-message-formats-Stream-Start"> + <term>Stream Start</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('S')</term> + <listitem> + <para> + Identifies the message as a stream start message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Stream-Stop"> + <term>Stream Stop</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('E')</term> + <listitem> + <para> + Identifies the message as a stream stop message. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Stream-Commit"> + <term>Stream Commit</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('c')</term> + <listitem> + <para> + Identifies the message as a stream commit message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the commit. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</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> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Stream-Abort"> + <term>Stream Abort</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('A')</term> + <listitem> + <para> + Identifies the message as a stream abort message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the subtransaction (will be same as xid of the transaction for top-level + transactions). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the abort. This field is available since protocol version + 4. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Abort timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). This field is + available since protocol version 4. + </para> + </listitem> + </varlistentry> + + </variablelist> + </listitem> + </varlistentry> + </variablelist> + + <para> + The following messages (Begin Prepare, Prepare, Commit Prepared, Rollback Prepared, Stream Prepare) + are available since protocol version 3. + </para> + + <variablelist> + <varlistentry id="protocol-logicalrep-message-formats-Begin-Prepare"> + <term>Begin Prepare</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('b')</term> + <listitem> + <para> + Identifies the message as the beginning of a prepared transaction message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the prepare. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Prepare timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem> + <para> + The user defined GID of the prepared transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Prepare"> + <term>Prepare</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('P')</term> + <listitem> + <para> + Identifies the message as a prepared transaction message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the prepare. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Prepare timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem> + <para> + The user defined GID of the prepared transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Commit-Prepared"> + <term>Commit Prepared</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('K')</term> + <listitem> + <para> + Identifies the message as the commit of a prepared transaction message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the commit of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the commit of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</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 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem> + <para> + The user defined GID of the prepared transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Rollback-Prepared"> + <term>Rollback Prepared</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('r')</term> + <listitem> + <para> + Identifies the message as the rollback of a prepared transaction message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the rollback of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Prepare timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Rollback timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem> + <para> + The user defined GID of the prepared transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + + <varlistentry id="protocol-logicalrep-message-formats-Stream-Prepare"> + <term>Stream Prepare</term> + <listitem> + <variablelist> + <varlistentry> + <term>Byte1('p')</term> + <listitem> + <para> + Identifies the message as a stream prepared transaction message. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int8(0)</term> + <listitem> + <para> + Flags; currently unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The LSN of the prepare. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (XLogRecPtr)</term> + <listitem> + <para> + The end LSN of the prepared transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int64 (TimestampTz)</term> + <listitem> + <para> + Prepare timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Int32 (TransactionId)</term> + <listitem> + <para> + Xid of the transaction. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>String</term> + <listitem> + <para> + The user defined GID of the prepared transaction. + </para> + </listitem> + </varlistentry> + </variablelist> + </listitem> + </varlistentry> + </variablelist> + + <para> + The following message parts are shared by the above messages. + </para> + + <variablelist> + <varlistentry id="protocol-logicalrep-message-formats-TupleData"> + <term>TupleData</term> + <listitem> + <variablelist> + <varlistentry> + <term>Int16</term> + <listitem> + <para> + Number of columns. + </para> + </listitem> + </varlistentry> + </variablelist> + + <para> + 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> |