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