-<Chapter Id="protocol">
-<DocInfo>
-<Author>
-<FirstName>Phil</FirstName>
-<Surname>Thompson</Surname>
-</Author>
-<Date>1998-08-08</Date>
-</DocInfo>
-<Title>Frontend/Backend Protocol</Title>
-
-<Para>
-<Note>
-<Para>
-Written by <ULink url="mailto:phil@river-bank.demon.co.uk">Phil Thompson</ULink>.
-Updates for protocol 2.0 by <ULink url="mailto:tgl@sss.pgh.pa.us">Tom Lane</ULink>.
-</Para>
-</Note>
-
-<Para>
-<ProductName>Postgres</ProductName> uses a message-based protocol for communication between frontends
-and backends. The protocol is implemented over <Acronym>TCP/IP</Acronym> and also on Unix sockets.
-<ProductName>Postgres</ProductName> v6.3 introduced version numbers into the protocol.
-This was done in such
-a way as to still allow connections from earlier versions of frontends, but
-this document does not cover the protocol used by those earlier versions.
-
-<Para>
-This document describes version 2.0 of the protocol, implemented in
-<ProductName>Postgres</ProductName> v6.4 and later.
-
-<Para>
-Higher level features built on this protocol (for example, how <FileName>libpq</FileName> passes
-certain environment variables after the connection is established)
-are covered elsewhere.
-
-<Sect1>
-<Title>Overview</Title>
-
-<Para>
-The three major components are the frontend (running on the client) and the
-postmaster and backend (running on the server). The postmaster and backend
-have different roles but may be implemented by the same executable.
-
-<Para>
-A frontend sends a startup packet to the postmaster. This includes the names
-of the user and the database the user wants to connect to. The postmaster then
-uses this, and the information in the pg_hba.conf(5) file to determine what
-further authentication information it requires the frontend to send (if any)
-and responds to the frontend accordingly.
-
-<Para>
-The frontend then sends any required authentication information. Once the
-postmaster validates this it responds to the frontend that it is authenticated
-and hands over the connection to a backend. The backend then sends a message
-indicating successful startup (normal case) or failure (for example, an
-invalid database name).
-
-<Para>
-Subsequent communications are query and result packets exchanged between the
-frontend and the backend. The postmaster takes no further part in ordinary
-query/result communication. (However, the postmaster is involved when the
-frontend wishes to cancel a query currently being executed by its backend.
-Further details about that appear below.)
-
-<Para>
-When the frontend wishes to disconnect it sends an appropriate packet and
-closes the connection without waiting for a response for the backend.
-
-<Para>
-Packets are sent as a data stream. The first byte determines what should be
-expected in the rest of the packet. The exception is packets sent from a
-frontend to the postmaster, which comprise a packet length then the packet
-itself. The difference is historical.
-
-<Sect1>
-<Title>Protocol</Title>
-
-<Para>
-This section describes the message flow. There are four different types of
-flows depending on the state of the connection:
-startup, query, function call, and termination.
-There are also special provisions for notification responses and command
-cancellation, which can occur at any time after the startup phase.
-
-
-<Sect2>
-<Title>Startup</Title>
-
-<Para>
-Startup is divided into an authentication phase and a backend startup phase.
-
-<Para>
-Initially, the frontend sends a StartupPacket. The postmaster uses this info
-and the contents of the pg_hba.conf(5) file to determine what authentication
-method the frontend must use. The postmaster then responds with one of the
-following messages:
-
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- ErrorResponse
-</Term>
-<ListItem>
-<Para>
- The postmaster then immediately closes the connection.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- AuthenticationOk
-</Term>
-<ListItem>
-<Para>
- The postmaster then hands over to the backend. The postmaster
- takes no further part in the communication.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- AuthenticationKerberosV4
-</Term>
-<ListItem>
-<Para>
- The frontend must then take part in a Kerberos V4
- authentication dialog (not described here) with the postmaster.
- If this is successful, the postmaster responds with an
- AuthenticationOk, otherwise it responds with an ErrorResponse.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- AuthenticationKerberosV5
-</Term>
-<ListItem>
-<Para>
- The frontend must then take part in a Kerberos V5
- authentication dialog (not described here) with the postmaster.
- If this is successful, the postmaster responds with an
- AuthenticationOk, otherwise it responds with an ErrorResponse.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- AuthenticationUnencryptedPassword
-</Term>
-<ListItem>
-<Para>
- The frontend must then send an UnencryptedPasswordPacket.
- If this is the correct password, the postmaster responds with
- an AuthenticationOk, otherwise it responds with an
- ErrorResponse.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- AuthenticationEncryptedPassword
-</Term>
-<ListItem>
-<Para>
- The frontend must then send an EncryptedPasswordPacket.
- If this is the correct password, the postmaster responds with
- an AuthenticationOk, otherwise it responds with an
- ErrorResponse.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-<Para>
-If the frontend does not support the authentication method requested by the
-postmaster, then it should immediately close the connection.
-
-<Para>
-After sending AuthenticationOk, the postmaster attempts to launch a backend
-process. Since this might fail, or the backend might encounter a failure
-during startup, the frontend must wait for the backend to acknowledge
-successful startup. The frontend should send no messages at this point.
-The possible messages from the backend during this phase are:
-
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- BackendKeyData
-</Term>
-<ListItem>
-<Para>
- This message is issued after successful backend startup.
- It 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>
- ReadyForQuery
-</Term>
-<ListItem>
-<Para>
- Backend startup is successful. The frontend may now issue
- query or function call messages.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- ErrorResponse
-</Term>
-<ListItem>
-<Para>
- Backend startup 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 query cycle. Depending on the coding needs of the frontend, it is
-reasonable to consider ReadyForQuery as starting a query cycle (and then
-BackendKeyData indicates successful conclusion of the startup phase),
-or to consider ReadyForQuery as ending the startup phase and each subsequent
-query cycle.
-
-
-<Sect2>
-<Title>Query</Title>
-
-<Para>
-A Query cycle is initiated by the frontend sending a Query message to the
-backend. The backend then sends one or more response messages depending
-on the contents of the query command string, and finally a ReadyForQuery
-response message. ReadyForQuery informs the frontend that it may safely
-send a new query or function call.
-
-<Para>
-The possible response messages from the backend are:
-
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- CompletedResponse
-</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
- relation. The frontend should then send a CopyDataRows
- message. The backend will then respond with a
- CompletedResponse message with a tag of "COPY".
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- CopyOutResponse
-</Term>
-<ListItem>
-<Para>
- The backend is ready to copy data from a relation to the
- frontend. It then sends a CopyDataRows message, and then a
- CompletedResponse message with a tag of "COPY".
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- CursorResponse
-</Term>
-<ListItem>
-<Para>
- The query was either an insert(l), delete(l), update(l),
- fetch(l) or a select(l) command.
- If the transaction has been
- aborted then the backend sends a CompletedResponse message with
- a tag of "*ABORT STATE*". Otherwise the following responses
- are sent.
-</Para>
-<Para>
- For an insert(l) command, the backend then sends a
- CompletedResponse message with a tag of "INSERT <Replaceable>oid</Replaceable> <Replaceable>rows</Replaceable>"
- where <Replaceable>rows</Replaceable> is the number of rows inserted, and <Replaceable>oid</Replaceable> is the
- object ID of the inserted row if <Replaceable>rows</Replaceable> is 1, otherwise <Replaceable>oid</Replaceable>
- is 0.
-</Para>
-<Para>
- For a delete(l) command, the backend then sends a
- CompletedResponse message with a tag of "DELETE <Replaceable>rows</Replaceable>" where
- <Replaceable>rows</Replaceable> is the number of rows deleted.
-</Para>
-<Para>
- For an update(l) command, the backend then sends a
- CompletedResponse message with a tag of "UPDATE <Replaceable>rows</Replaceable>" where
- <Replaceable>rows</Replaceable> is the number of rows deleted.
-</Para>
-<Para>
- For a fetch(l) or select(l) command, the backend sends a
- RowDescription message. This is then followed by an AsciiRow
- or BinaryRow message (depending on whether a binary cursor was
- specified) for each row being returned to the frontend.
- Finally, the backend sends a CompletedResponse message with a
- tag of "SELECT".
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- EmptyQueryResponse
-</Term>
-<ListItem>
-<Para>
- An empty query string was recognized. (The need to specially
- distinguish this case is historical.)
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- ErrorResponse
-</Term>
-<ListItem>
-<Para>
- An error has occurred.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- ReadyForQuery
-</Term>
-<ListItem>
-<Para>
- Processing of the query string is complete. A separate
- message is sent to indicate this because the query string
- may contain multiple SQL commands. (CompletedResponse 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, ie. the backend
- will continue processing the command.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-<Para>
-A frontend must be prepared to accept ErrorResponse and NoticeResponse
-messages whenever it is expecting any other type of message.
-
-<Para>
-Actually, it is possible for NoticeResponse to arrive even when the frontend
-is not expecting any kind of message, that is, the backend is nominally idle.
-(In particular, the backend can be commanded to terminate by its postmaster.
-In that case it will send a NoticeResponse before closing the connection.)
-It is recommended that the frontend check for such asynchronous notices just
-before issuing any new command.
-
-<Para>
-Also, if the frontend issues any listen(l) commands then it must be prepared
-to accept NotificationResponse messages at any time; see below.
-
-
-<Sect2>
-<Title>Function Call</Title>
-
-<Para>
-A Function Call cycle is initiated by the frontend sending a FunctionCall
-message to the backend. The backend then sends one or more response messages
-depending on the results of the function call, and finally a ReadyForQuery
-response message. ReadyForQuery informs the frontend that it may safely send
-a new query or function call.
-
-<Para>
-The possible response messages from the backend are:
-
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- ErrorResponse
-</Term>
-<ListItem>
-<Para>
- An error has occurred.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- FunctionResultResponse
-</Term>
-<ListItem>
-<Para>
- The function call was executed and returned a result.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- FunctionVoidResponse
-</Term>
-<ListItem>
-<Para>
- The function call was executed and returned no result.
-</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, ie. the backend
- will continue processing the command.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-<Para>
-A frontend must be prepared to accept ErrorResponse and NoticeResponse
-messages whenever it is expecting any other type of message. Also,
-if it issues any listen(l) commands then it must be prepared to accept
-NotificationResponse messages at any time; see below.
-
-
-<Sect2>
-<Title>Notification Responses</Title>
-
-<Para>
-If a frontend issues a listen(l) command, then the backend will send a
-NotificationResponse message (not to be confused with NoticeResponse!)
-whenever a notify(l) command is executed for the same notification name.
-
-<Para>
-Notification responses are permitted at any point in the protocol (after
-startup), except within another backend message. Thus, the frontend
-must be prepared to recognize a NotificationResponse message whenever it is
-expecting any message. Indeed, it should be able to handle
-NotificationResponse messages even when it is not engaged in a query.
-
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- NotificationResponse
-</Term>
-<ListItem>
-<Para>
- A notify(l) command has been executed for a name for which
- a previous listen(l) command was executed. Notifications
- may be sent at any time.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-<Para>
-It may be worth pointing out that the names used in listen and notify
-commands need not have anything to do with names of relations (tables)
-in the SQL database. Notification names are simply arbitrarily chosen
-condition names.
-
-
-<Sect2>
-<Title>Cancelling Requests in Progress</Title>
-
-<Para>
-During the processing of a query, the frontend may request cancellation of the
-query by sending an appropriate request to the postmaster. The cancel request
-is not sent directly 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>
-To issue a cancel request, the frontend opens a new connection to the
-postmaster and sends a CancelRequest message, rather than the StartupPacket
-message that would ordinarily be sent across a new connection. The postmaster
-will process this request and then close the connection. For security
-reasons, no direct reply is made to the cancel request message.
-
-<Para>
-A CancelRequest message will be ignored unless it contains the same key data
-(PID and secret key) passed to the frontend during connection startup. If the
-request matches the PID and secret key for a currently executing backend, the
-postmaster signals the backend to abort processing of the current query.
-
-<Para>
-The cancellation signal may or may not have any effect --- for example, if it
-arrives after the backend has finished processing the query, then it will have
-no effect. If the cancellation is effective, it results in the current
-command being terminated early with an error message.
-
-<Para>
-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>
-Since the cancel request is sent to the postmaster and not across the
-regular frontend/backend communication link, it is possible for the cancel
-request to be issued by any process, not just the frontend whose query is
-to be canceled. This may have some benefits of flexibility in building
-multiple-process applications. It also introduces a security risk, in that
-unauthorized persons might try to cancel queries. The security risk is
-addressed by requiring a dynamically generated secret key to be supplied
-in cancel requests.
-
-
-<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 the
-message, the backend immediately closes the connection and terminates.
-
-<Para>
-An ungraceful termination may occur due to software failure (i.e., core dump)
-at either end. 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 postmaster, if it doesn't want
-to terminate itself.
-
-
-<Sect1>
-<Title>Message Data Types</Title>
-
-<Para>
+<!-- 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, and then the server follows that protocol
+ if it is able.
+ </para>
+
+ <para>
+ In order to serve multiple clients efficiently, the server launches
+ a new <quote>backend</> 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</> and <quote>server</> are
+ interchangeable; likewise <quote>frontend</> and <quote>client</>
+ 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</>)
+ 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</> protocol, the frontend
+ just sends a textual query string, which is parsed and immediately
+ executed by the backend. In the <quote>extended query</> 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</>.
+ </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</> and
+ <firstterm>portals</>. A prepared statement represents the result of
+ parsing, semantic analysis, and (optionally) planning of a textual query
+ string.
+ A prepared statement is not necessarily ready to execute, because it might
+ lack specific values for <firstterm>parameters</>. A portal represents
+ a ready-to-execute or already-partially-executed statement, with any
+ missing parameter values filled in. (For <command>SELECT</> 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</> statements.)
+ </para>
+
+ <para>
+ The overall execution cycle consists of a <firstterm>parse</> step,
+ which creates a prepared statement from a textual query string; a
+ <firstterm>bind</> step, which creates a portal given a prepared
+ statement and values for any needed parameters; and an
+ <firstterm>execute</> step that runs a portal's query. In the case of
+ a query that returns rows (<command>SELECT</>, <command>SHOW</>, 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</> 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</>. As of <productname>PostgreSQL</> 7.4
+ the only supported formats are <quote>text</> and <quote>binary</>,
+ but the protocol makes provision for future extensions. The desired
+ format for any value is specified by a <firstterm>format code</>.
+ 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 and SSPI, 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 and SSPI, 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.
+ </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 encrypted via MD5, using the 4-character salt
+ specified in the AuthenticationMD5Password message. If
+ this is the correct password, the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ </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.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationGSS</term>
+ <listitem>
+ <para>
+ The frontend must now initiate a GSSAPI negotiation. The frontend
+ will send a PasswordMessage 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 a SSPI negotiation. The frontend
+ will send a PasswordMessage 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 PasswordMessage. 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>
+
+ </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), 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</> query (or other queries that
+ return row sets, such as <command>EXPLAIN</> or <command>SHOW</>)
+ normally consists of RowDescription, zero or more
+ DataRow messages, and then CommandComplete.
+ <command>COPY</> to or from the frontend invokes special protocol
+ as described in <xref linkend="protocol-copy">.
+ All other query types normally produce only
+ a CommandComplete message.
+ </para>
+
+ <para>
+ Since a query string could contain several queries (separated by
+ semicolons), there might be several such response sequences before the
+ backend finishes processing the query string. ReadyForQuery is issued
+ when the entire string has been processed and the backend is ready to
+ accept a new query string.
+ </para>
+
+ <para>
+ If a completely empty (no contents other than whitespace) query string
+ is received, the response is EmptyQueryResponse followed by ReadyForQuery.
+ </para>
+
+ <para>
+ In the event of an error, ErrorResponse is issued followed by
+ ReadyForQuery. All further processing of the query string is aborted by
+ ErrorResponse (even if more queries remained in it). Note that this
+ 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</> from a cursor
+ declared with the <literal>BINARY</> option. In that case, the
+ retrieved values are in binary format. The format codes given in
+ the RowDescription message tell which format is being used.
+ </para>
+
+ <para>
+ A frontend must be prepared to accept ErrorResponse and
+ NoticeResponse messages whenever it is expecting any other type of
+ message. See also <xref linkend="protocol-async"> concerning messages
+ that the backend 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>
+ </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>$</><replaceable>n</>)
+ used in the query string. Another special case is that a parameter's
+ type can be specified as <type>void</> (that is, the OID of the
+ <type>void</> pseudotype). This is meant to allow parameter symbols
+ to be used for function parameters that are actually OUT parameters.
+ Ordinarily there is no context in which a <type>void</> parameter
+ could be used, but if such a parameter symbol appears in a function's
+ parameter list, it is effectively ignored. For example, a function
+ call such as <literal>foo($1,$2,$3,$4)</> could match a function with
+ two IN and two OUT arguments, if <literal>$3</> and <literal>$4</>
+ are specified as having type <type>void</>.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ The query string contained in a Parse message cannot include more
+ than one SQL statement; else a syntax error is reported. This
+ restriction does not exist in the simple-query protocol, but it
+ does exist in the extended protocol, because allowing prepared
+ statements or portals to contain multiple commands would complicate
+ the protocol unduly.
+ </para>
+ </note>
+
+ <para>
+ If successfully created, a named prepared-statement object lasts till
+ the end of the current session, unless explicitly destroyed. An unnamed
+ prepared statement lasts only until the next Parse statement specifying
+ the unnamed statement as destination is issued. (Note that a simple
+ Query message also destroys the unnamed statement.) Named prepared
+ statements must be explicitly closed before they can be redefined by
+ a Parse message, but this is not required for the unnamed statement.
+ Named prepared statements can also be created and accessed at the SQL
+ command level, using <command>PREPARE</> and <command>EXECUTE</>.
+ </para>
+
+ <para>
+ Once a prepared statement exists, it can be readied for execution using a
+ Bind message. The Bind message gives the name of the source prepared
+ statement (empty string denotes the unnamed prepared statement), the name
+ of the destination portal (empty string denotes the unnamed portal), and
+ the values to use for any parameter placeholders present in the prepared
+ statement. The
+ supplied parameter set must match those needed by the prepared statement.
+ (If you declared any <type>void</> parameters in the Parse message,
+ pass NULL values for them in the Bind message.)
+ Bind also specifies the format to use for any data returned
+ by the query; the format can be specified overall, or per-column.
+ The response is either BindComplete or ErrorResponse.
+ </para>
+
+ <note>
+ <para>
+ The choice between text and binary output is determined by the format
+ codes given in Bind, regardless of the SQL command involved. The
+ <literal>BINARY</> attribute in cursor declarations is irrelevant when
+ using extended query protocol.
+ </para>
+ </note>
+
+ <para>
+ Query planning for named prepared-statement objects occurs when the Parse
+ message is processed. If a query will be repeatedly executed with
+ different parameters, it might be beneficial to send a single Parse message
+ containing a parameterized query, followed by multiple Bind
+ and Execute messages. This will avoid replanning the query on each
+ execution.
+ </para>
+
+ <para>
+ The unnamed prepared statement is likewise planned during Parse processing
+ if the Parse message defines no parameters. But if there are parameters,
+ query planning occurs every time Bind parameters are supplied. This allows the
+ planner to make use of the actual values of the parameters provided by
+ each Bind message, rather than use generic estimates.
+ </para>
+
+ <note>
+ <para>
+ Query plans generated from a parameterized query might be less
+ efficient than query plans generated from an equivalent query with actual
+ parameter values substituted. The query planner cannot make decisions
+ based on actual parameter values (for example, index selectivity) when
+ planning a parameterized query assigned to a named prepared-statement
+ object. This possible penalty is avoided when using the unnamed
+ statement, since it is not planned until actual parameter values are
+ available. The cost is that planning must occur afresh for each Bind,
+ even if the query stays the same.
+ </para>
+ </note>
+
+ <para>
+ If successfully created, a named portal object lasts till the end of the
+ current transaction, unless explicitly destroyed. An unnamed portal is
+ destroyed at the end of the transaction, or as soon as the next Bind
+ statement specifying the unnamed portal as destination is issued. (Note
+ that a simple Query message also destroys the unnamed portal.) Named
+ portals must be explicitly closed before they can be redefined by a Bind
+ message, but this is not required for the unnamed portal.
+ Named portals can also be created and accessed at the SQL
+ command level, using <command>DECLARE CURSOR</> and <command>FETCH</>.
+ </para>
+
+ <para>
+ Once a portal exists, it can be executed using an Execute message.
+ The Execute message specifies the portal name (empty string denotes the
+ unnamed portal) and
+ a maximum result-row count (zero meaning <quote>fetch all rows</>).
+ The result-row count is only meaningful for portals
+ containing commands that return row sets; in other cases the command is
+ always executed to completion, and the row count is ignored.
+ The possible
+ responses to Execute are the same as those described above for queries
+ issued via simple query protocol, except that Execute doesn't cause
+ ReadyForQuery or RowDescription to be issued.
+ </para>
+
+ <para>
+ If Execute terminates before completing the execution of a portal
+ (due to reaching a nonzero result-row count), it will send a
+ PortalSuspended message; the appearance of this message tells the frontend
+ that another Execute should be issued against the same portal to
+ complete the operation. The CommandComplete message indicating
+ completion of the source SQL command is not sent until
+ the portal's execution is completed. Therefore, an Execute phase is
+ always terminated by the appearance of exactly one of these messages:
+ CommandComplete, EmptyQueryResponse (if the portal was created from
+ an empty query string), ErrorResponse, or PortalSuspended.
+ </para>
+
+ <para>
+ At completion of each series of extended-query messages, the frontend
+ should issue a Sync message. This parameterless message causes the
+ backend to close the current transaction if it's not inside a
+ <command>BEGIN</>/<command>COMMIT</> transaction block (<quote>close</>
+ meaning to commit if no error, or roll back if error). Then a
+ ReadyForQuery response is issued. The purpose of Sync is to provide
+ a resynchronization point for error recovery. When an error is detected
+ while processing any extended-query message, the backend issues
+ ErrorResponse, then reads and discards messages until a Sync is reached,
+ then issues ReadyForQuery and returns to normal message processing.
+ (But note that no skipping occurs if an error is detected
+ <emphasis>while</> processing Sync — this ensures that there is one
+ and only one ReadyForQuery sent for each Sync.)
+ </para>
+
+ <note>
+ <para>
+ Sync does not cause a transaction block opened with <command>BEGIN</>
+ to be closed. It is possible to detect this situation since the
+ ReadyForQuery message includes transaction status information.
+ </para>
+ </note>
+
+ <para>
+ In addition to these fundamental, required operations, there are several
+ optional operations that can be used with extended-query protocol.
+ </para>
+
+ <para>
+ The Describe message (portal variant) specifies the name of an existing
+ portal (or an empty string for the unnamed portal). The response is a
+ RowDescription message describing the rows that will be returned by
+ executing the portal; or a NoData message if the portal does not contain a
+ query that will return rows; or ErrorResponse if there is no such portal.
+ </para>
+
+ <para>
+ The Describe message (statement variant) specifies the name of an existing
+ prepared statement (or an empty string for the unnamed prepared
+ statement). The response is a ParameterDescription message describing the
+ parameters needed by the statement, followed by a RowDescription message
+ describing the rows that will be returned when the statement is eventually
+ executed (or a NoData message if the statement will not return rows).
+ ErrorResponse is issued if there is no such prepared statement. Note that
+ since Bind has not yet been issued, the formats to be used for returned
+ columns are not yet known to the backend; the format code fields in the
+ RowDescription message will be zeroes in this case.
+ </para>
+
+ <tip>
+ <para>
+ In most scenarios the frontend should issue one or the other variant
+ of Describe before issuing Execute, to ensure that it knows how to
+ interpret the results it will get back.
+ </para>
+ </tip>
+
+ <para>
+ The Close message closes an existing prepared statement or portal
+ and releases resources. It is not an error to issue Close against
+ a nonexistent statement or portal name. The response is normally
+ CloseComplete, but could be ErrorResponse if some difficulty is
+ encountered while releasing resources. Note that closing a prepared
+ statement implicitly closes any open portals that were constructed
+ from that statement.
+ </para>
+
+ <para>
+ The Flush message does not cause any specific output to be generated,
+ but forces the backend to deliver any data pending in its output
+ buffers. A Flush must be sent after any extended-query command except
+ Sync, if the frontend wishes to examine the results of that command before
+ issuing more commands. Without Flush, messages returned by the backend
+ will be combined into the minimum possible number of packets to minimize
+ network overhead.
+ </para>
+
+ <note>
+ <para>
+ The simple Query message is approximately equivalent to the series Parse,
+ Bind, portal Describe, Execute, Close, Sync, using the unnamed prepared
+ statement and portal objects and no parameters. One difference is that
+ it will accept multiple SQL statements in the query string, automatically
+ performing the bind/describe/execute sequence for each one in succession.
+ Another difference is that it will not return ParseComplete, BindComplete,
+ CloseComplete, or NoData messages.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Function Call</title>
+
+ <para>
+ The Function Call sub-protocol allows the client to request a direct
+ call of any function that exists in the database's
+ <structname>pg_proc</structname> system catalog. The client must have
+ execute permission for the function.
+ </para>
+
+ <note>
+ <para>
+ The Function Call sub-protocol is a legacy feature that is probably best
+ avoided in new code. Similar results can be accomplished by setting up
+ a prepared statement that does <literal>SELECT function($1, ...)</>.
+ The Function Call cycle can then be replaced with Bind/Execute.
+ </para>
+ </note>
+
+ <para>
+ A Function Call cycle is initiated by the frontend sending a
+ FunctionCall message to the backend. The backend then sends one
+ or more response messages depending on the results of the function
+ call, and finally a ReadyForQuery response message. ReadyForQuery
+ informs the frontend that it 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 allows high-speed bulk data transfer
+ to or from the server. Copy-in and copy-out operations each switch
+ the connection into a distinct sub-protocol, which lasts until the
+ operation is completed.
+ </para>
+
+ <para>
+ Copy-in mode (data transfer to the server) is initiated when the
+ backend executes a <command>COPY FROM STDIN</> SQL statement. The backend
+ sends a CopyInResponse message to the frontend. The frontend should
+ then send zero or more CopyData messages, forming a stream of input
+ data. (The message boundaries are not required to have anything to do
+ with row boundaries, although that is often a reasonable choice.)
+ The frontend can terminate the copy-in mode by sending either a CopyDone
+ message (allowing successful termination) or a CopyFail message (which
+ will cause the <command>COPY</> SQL statement to fail with an
+ error). The backend then reverts to the command-processing mode it was
+ in before the <command>COPY</> started, which will be either simple or
+ extended query protocol. It will next send either CommandComplete
+ (if successful) or ErrorResponse (if not).
+ </para>
+
+ <para>
+ In the event of a backend-detected error during copy-in mode (including
+ receipt of a CopyFail message), the backend will issue an ErrorResponse
+ message. If the <command>COPY</> command was issued via an extended-query
+ message, the backend will now discard frontend messages until a Sync
+ message is received, then it will issue ReadyForQuery and return to normal
+ processing. If the <command>COPY</> command was issued in a simple
+ Query message, the rest of that message is discarded and ReadyForQuery
+ is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail
+ messages issued by the frontend will simply be dropped.
+ </para>
+
+ <para>
+ The backend will ignore Flush and Sync messages received during copy-in
+ mode. Receipt of any other non-copy message type constitutes an error
+ that will abort the copy-in state as described above. (The exception for
+ Flush and Sync is for the convenience of client libraries that always
+ send Flush or Sync after an Execute message, without checking whether
+ the command to be executed is a <command>COPY FROM STDIN</>.)
+ </para>
+
+ <para>
+ Copy-out mode (data transfer from the server) is initiated when the
+ backend executes a <command>COPY TO STDOUT</> SQL statement. The backend
+ sends a CopyOutResponse message to the frontend, followed by
+ zero or more CopyData messages (always one per row), followed by CopyDone.
+ The backend then reverts to the command-processing mode it was
+ in before the <command>COPY</> started, and sends CommandComplete.
+ The frontend cannot abort the transfer (except by closing the connection
+ or issuing a Cancel request),
+ but it can discard unwanted CopyData and CopyDone messages.
+ </para>
+
+ <para>
+ In the event of a backend-detected error during copy-out mode,
+ the backend will issue an ErrorResponse message and revert to normal
+ processing. The frontend should treat receipt of ErrorResponse 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</> 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 the connection is terminated. See <xref
+ linkend="protocol-replication">.
+ </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</>
+ operation will use the same format, but the message design does not
+ assume this.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="protocol-async">
+ <title>Asynchronous Operations</title>
+
+ <para>
+ There are several cases in which the backend will send messages that
+ are not specifically prompted by the frontend's command stream.
+ Frontends must be prepared to deal with these messages at any time,
+ even when not engaged in a query.
+ At minimum, one should check for these cases before beginning to
+ read a query response.
+ </para>
+
+ <para>
+ It is possible for NoticeResponse messages to be generated due to
+ outside activity; for example, if the database administrator commands
+ a <quote>fast</> database shutdown, the backend will send a NoticeResponse
+ indicating this fact before closing the connection. Accordingly,
+ frontends should always be prepared to accept and display NoticeResponse
+ messages, even when the connection is nominally idle.
+ </para>
+
+ <para>
+ ParameterStatus messages will be generated whenever the active
+ value changes for any of the parameters the backend believes the
+ frontend should know about. Most commonly this occurs in response
+ to a <command>SET</> SQL command executed by the frontend, and
+ this case is effectively synchronous — but it is also possible
+ for parameter status changes to occur because the administrator
+ changed a configuration file and then sent the
+ <systemitem>SIGHUP</systemitem> signal to the 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
+ <literal>server_version</>,
+ <literal>server_encoding</>,
+ <literal>client_encoding</>,
+ <literal>application_name</>,
+ <literal>is_superuser</>,
+ <literal>session_authorization</>,
+ <literal>DateStyle</>,
+ <literal>IntervalStyle</>,
+ <literal>TimeZone</>,
+ <literal>integer_datetimes</>, and
+ <literal>standard_conforming_strings</>.
+ (<literal>server_encoding</>, <literal>TimeZone</>, and
+ <literal>integer_datetimes</> were not reported by releases before 8.0;
+ <literal>standard_conforming_strings</> was not reported by releases
+ before 8.1;
+ <literal>IntervalStyle</> was not reported by releases before 8.4;
+ <literal>application_name</> was not reported by releases before 9.0.)
+ Note that
+ <literal>server_version</>,
+ <literal>server_encoding</> and
+ <literal>integer_datetimes</>
+ are pseudo-parameters that cannot change after startup.
+ This set might change in the future, or even become configurable.
+ Accordingly, a frontend should simply ignore ParameterStatus for
+ parameters that it does not understand or care about.
+ </para>
+
+ <para>
+ If a frontend issues a <command>LISTEN</command> command, then the
+ backend will send a NotificationResponse message (not to be
+ confused with NoticeResponse!) whenever a
+ <command>NOTIFY</command> command is executed for the same
+ 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>Cancelling 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>COMMIT</>
+ 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</> 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</> or <literal>N</>, 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</>, 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</>, send the usual StartupMessage and proceed without
+ encryption.
+ </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</>. 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>
+ 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>
+ </sect1>
+
+<sect1 id="protocol-replication">
+<title>Streaming Replication Protocol</title>
+
+<para>
+To initiate streaming replication, the frontend sends the
+<literal>replication</> parameter in the startup message. This tells the
+backend to go into walsender mode, wherein a small set of replication commands
+can be issued instead of SQL statements. Only the simple query protocol can be
+used in walsender mode.
+
+The commands accepted in walsender mode are:
+
+<variablelist>
+ <varlistentry>
+ <term>IDENTIFY_SYSTEM</term>
+ <listitem>
+ <para>
+ Requests the server to identify itself. Server replies with a result
+ set of a single row, containing two fields:
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ systemid
+ </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>
+ timeline
+ </term>
+ <listitem>
+ <para>
+ Current TimelineID. Also useful to check that the standby is
+ consistent with the master.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>START_REPLICATION <replaceable>XXX</>/<replaceable>XXX</></term>
+ <listitem>
+ <para>
+ Instructs server to start streaming WAL, starting at
+ WAL position <replaceable>XXX</>/<replaceable>XXX</>.
+ The server can reply with an error, e.g. 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.
+ WAL will continue to be streamed until the connection is broken;
+ no further commands will be accepted.
+ </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 in each CopyData message follows this format:
+ </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>
+ Byte8
+ </term>
+ <listitem>
+ <para>
+ The starting point of the WAL data in this message, given in
+ XLogRecPtr format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte8
+ </term>
+ <listitem>
+ <para>
+ The current end of WAL on the server, given in
+ XLogRecPtr format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte8
+ </term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission,
+ given in TimestampTz format.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Byte<replaceable>n</replaceable>
+ </term>
+ <listitem>
+ <para>
+ A section of the WAL data stream.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ A single WAL record is never split across two CopyData 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 CopyData messages.
+ </para>
+ <para>
+ Note that all fields within the WAL data and the above-described header
+ will be in the sending server's native format. Endianness, and the
+ format for the timestamp, are unpredictable unless the receiver has
+ verified that the sender's system identifier matches its own
+ <filename>pg_control</> contents.
+ </para>
+ <para>
+ If the WAL sender process is terminated normally (during postmaster
+ shutdown), it will send a CommandComplete message before exiting.
+ This might not happen during an abnormal shutdown, of course.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>BASE_BACKUP [<literal>LABEL</literal> <replaceable>'label'</replaceable>] [<literal>PROGRESS</literal>] [<literal>FAST</literal>]</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</></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 may as such have a negative impact on the
+ performance - in particular it may take longer before the first data
+ is streamed. Since the database files can change during the backup,
+ the size is only approximate and may both grow and shrink between
+ the time of approximation and the sending of the actual files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FAST</></term>
+ <listitem>
+ <para>
+ Request a fast checkpoint.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ When the backup is started, the server will first send a header in
+ ordinary result set format, followed by one or more CopyResponse
+ results, one for PGDATA and one for each additional tablespace other
+ than <literal>pg_default</> and <literal>pg_global</>. The data in
+ the CopyResponse results will be a tar format (using ustar00
+ extensions) dump of the tablespace contents.
+ </para>
+ <para>
+ The header is an ordinary resultset with one row for each tablespace.
+ The fields in this row are:
+ <variablelist>
+ <varlistentry>
+ <term>spcoid</term>
+ <listitem>
+ <para>
+ The oid of the tablespace, or <literal>NULL</> if it's the base
+ directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>spclocation</term>
+ <listitem>
+ <para>
+ The full path of the tablespace directory, or <literal>NULL</>
+ if it's the base directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>size</term>
+ <listitem>
+ <para>
+ The approximate size of the tablespace, if progress report has
+ been requested; otherwise it's <literal>NULL</>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </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</> files or other files added to the same
+ directory. The only excluded files are:
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <filename>postmaster.pid</>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_xlog</> (including subdirectories)
+ </para>
+ </listitem>
+ </itemizedlist>
+ Owner, group and file mode are set if the underlying filesystem on
+ the server supports it.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</para>
+
+</sect1>
+
+<sect1 id="protocol-message-types">
+<title>Message Data Types</title>
+
+<para>
This section describes the base data types used in messages.
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- Int<Replaceable>n</Replaceable>(<Replaceable>i</Replaceable>)
-</Term>
-<ListItem>
-<Para>
- An <Replaceable>n</Replaceable> bit integer in network byte order.
- If <Replaceable>i</Replaceable> is specified it
- is the literal value. Eg. Int16, Int32(42).
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString<Replaceable>n</Replaceable>(<Replaceable>s</Replaceable>)
-</Term>
-<ListItem>
-<Para>
- A character array of exactly <Replaceable>n</Replaceable> bytes interpreted as a '\0'
- terminated string. The '\0' is omitted if there is
- insufficient room. If <Replaceable>s</Replaceable> is specified it is the literal value.
- Eg. LimString32, LimString64("user").
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String(<Replaceable>s</Replaceable>)
-</Term>
-<ListItem>
-<Para>
- A conventional C '\0' terminated string with no length
- limitation. A frontend should always read the full string
- even though it may have to discard characters if its buffers
- aren't big enough.
-<Note>
-<Para>
-Is 8193 bytes the largest allowed size?
-</Para>
-</Note>
- If <Replaceable>s</Replaceable> is specified it is the literal value.
- Eg. String, String("user").
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>(<Replaceable>c</Replaceable>)
-</Term>
-<ListItem>
-<Para>
- Exactly <Replaceable>n</Replaceable> bytes. If <Replaceable>c</Replaceable> is specified it is the literal
- value. Eg. Byte, Byte1('\n').
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-<Sect1>
-<Title>Message Formats</Title>
-
-<Para>
-This section describes the detailed format of each message. Each can be sent
-by either a frontend (F), a postmaster/backend (B), or both (F & B).
-
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
-AsciiRow (B)
-</Term>
-<ListItem>
-<Para>
-<VariableList>
-<VarListEntry>
-<Term>
- Byte1('D')
-</Term>
-<ListItem>
-<Para>
- Identifies the message as an <Acronym>ASCII</Acronym> data row.
- (A prior RowDescription message defines the number of
- fields in the row and their data types.)
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
-
- A bit map with one bit for each field in the row. The 1st
- field corresponds to bit 7 of the 1st byte, the 2nd field
- corresponds to bit 6 of the 1st byte, the 8th field corresponds
- to bit 0 of the 1st byte, the 9th field corresponds to bit 8 of
- the 2nd byte, and so on. The bit is set if the value of the
- corresponding field is not NULL.
-</Para>
-<Para>
- Then, for each field with a non-NULL value, there is the following:
-<VariableList>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the size of the value of the field, including
- this size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
- Specifies the value of the field itself in <Acronym>ASCII</Acronym>
- characters. <Replaceable>n</Replaceable> is the above size minus 4.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+<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(0)
-</Term>
-<ListItem>
-<Para>
- Specifies that the authentication was successful.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-AuthenticationKerberosV4 (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(1)
-</Term>
-<ListItem>
-<Para>
- Specifies that Kerberos V4 authentication is required.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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(2)
-</Term>
-<ListItem>
-<Para>
- Specifies that Kerberos V5 authentication is required.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-AuthenticationUnencryptedPassword (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(3)
-</Term>
-<ListItem>
-<Para>
- Specifies that an unencrypted password is required.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-AuthenticationEncryptedPassword (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(4)
-</Term>
-<ListItem>
-<Para>
- Specifies that an encrypted password is required.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte2
-</Term>
-<ListItem>
-<Para>
- The salt to use when encrypting the password.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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>
+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>
+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>
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
-</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>
-BinaryRow (B)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Byte1('B')
-</Term>
-<ListItem>
-<Para>
- Identifies the message as a binary data row.
- (A prior RowDescription message defines the number of
- fields in the row and their data types.)
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
- A bit map with one bit for each field in the row. The 1st
- field corresponds to bit 7 of the 1st byte, the 2nd field
- corresponds to bit 6 of the 1st byte, the 8th field corresponds
- to bit 0 of the 1st byte, the 9th field corresponds to bit 8 of
- the 2nd byte, and so on. The bit is set if the value of the
- corresponding field is not NULL.
-</Para>
-<Para>
- Then, for each field with a non-NULL value, there is the following:
-<VariableList>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the size of the value of the field, excluding
- this size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
- Specifies the value of the field itself in binary
- format. <Replaceable>n</Replaceable> is the above size.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> 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</>]
+</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</> 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</>]
+</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>
- The size of the packet in bytes.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32(80877102)
-</Term>
-<ListItem>
-<Para>
- The cancel request code. The value is chosen to contain
- "1234" in the most significant 16 bits, and "5678" in the
- least 16 significant 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>
-CompletedResponse (B)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Byte1('C')
-</Term>
-<ListItem>
-<Para>
- Identifies the message as a completed response.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The command tag. This is usually (but not always) a single
- word that identifies which SQL command was completed.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-CopyDataRows (B & F)
-</Term>
-<ListItem>
-<Para>
- This is a stream of rows where each row is terminated by a Byte1('\n').
- This is then followed by the sequence Byte1('\\'), Byte1('.'),
- Byte1('\n').
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> in the most significant 16 bits, and <literal>5678</> in the
+ least 16 significant 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</>' to close a prepared statement; or
+ '<literal>P</>' 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> is the object ID
+ of the inserted row if <replaceable>rows</replaceable> is 1
+ and the target table has OIDs;
+ otherwise <replaceable>oid</replaceable> is 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 a CopyDataRows message.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</>]
+</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 a CopyDataRows message.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-CursorResponse (B)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Byte1('P')
-</Term>
-<ListItem>
-<Para>
- Identifies the message as a cursor response.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The name of the cursor. This will be "blank" if the cursor is
- implicit.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</>]
+</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</> below).
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ Int16[<replaceable>N</>]
+</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</>' to describe a prepared statement; or
+ '<literal>P</>' 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.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String("")
-</Term>
-<ListItem>
-<Para>
- Unused.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-EncryptedPasswordPacket (F)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- The size of the packet in bytes.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The encrypted (using crypt()) password.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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>
- String
-</Term>
-<ListItem>
-<Para>
- The error message itself.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</>.
+</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>
- String("")
-</Term>
-<ListItem>
-<Para>
- Unused.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the object ID of the function to call.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the number of arguments being supplied to the
- function.
-</Para>
-<Para>
- Then, for each argument, there is the following:
-<VariableList>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the size of the value of the argument,
- excluding this size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
- Specifies the value of the field itself in binary
- format. <Replaceable>n</Replaceable> is the above size.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-<Para>
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-FunctionResultResponse (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>
- Byte1('G')
-</Term>
-<ListItem>
-<Para>
- Specifies that a nonempty result was returned.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the size of the value of the result, excluding this
- size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte<Replaceable>n</Replaceable>
-</Term>
-<ListItem>
-<Para>
- Specifies the value of the result itself in binary format.
- <Replaceable>n</Replaceable> is the above size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Byte1('0')
-</Term>
-<ListItem>
-<Para>
- Unused. (Strictly speaking, FunctionResultResponse and
- FunctionVoidResponse are the same thing but with some optional
- parts to the message.)
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-FunctionVoidResponse (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>
- Byte1('0')
-</Term>
-<ListItem>
-<Para>
- Specifies that an empty result was returned.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> 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</>]
+</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>
+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>
- String
-</Term>
-<ListItem>
-<Para>
- The notice message itself.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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>
- The process ID of the backend process.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The name of the relation that the notify has been raised on.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</> 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 and SSPI response messages
+ (which is really a design error, since the contained data
+ is not a null-terminated string in that case, but can be
+ arbitrary binary data).
+</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 query.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The query string itself.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</>' if idle (not in
+ a transaction block); '<literal>T</>' if in a transaction
+ block; or '<literal>E</>' 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>
- Int16
-</Term>
-<ListItem>
-<Para>
- Specifies the number of fields in a row (and may be zero).
-</Para>
-<Para>
- Then, for each field, there is the following:
-<VariableList>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- Specifies the field name.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the object ID of the field type.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int16
-</Term>
-<ListItem>
-<Para>
- Specifies the type size.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- Specifies the type modifier.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-StartupPacket (F)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Int32(296)
-</Term>
-<ListItem>
-<Para>
- The size of the packet in bytes.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- The protocol version number. The most significant 16 bits are
- the major version number. The least 16 significant bits are
- the minor version number.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString64
-</Term>
-<ListItem>
-<Para>
- The database name, defaults to the user name if omitted.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString32
-</Term>
-<ListItem>
-<Para>
- The user name.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString64
-</Term>
-<ListItem>
-<Para>
- Any additional command line arguments to be passed to the
- backend by the postmaster.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString64
-</Term>
-<ListItem>
-<Para>
- Unused.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- LimString64
-</Term>
-<ListItem>
-<Para>
- The optional tty the backend should use for debugging messages.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
+</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</>).
+ 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</>).
+ 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>
+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</> in the most significant 16 bits, and <literal>5679</> in the
+ least 16 significant 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</> 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</>
+</term>
+<listitem>
+<para>
+ The database user name to connect as. Required;
+ there is no default.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ <literal>database</>
+</term>
+<listitem>
+<para>
+ The database to connect to. Defaults to the user name.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+ <literal>options</>
+</term>
+<listitem>
+<para>
+ Command-line arguments for the backend. (This is
+ deprecated in favor of setting individual run-time
+ parameters.)
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+ In addition to the above, any run-time parameter that can be
+ set at backend start time might be listed. Such settings
+ will be applied during backend start (after parsing the
+ command-line options if any). The values 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>
-</VariableList>
-
-
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-UnencryptedPasswordPacket (F)
-</Term>
-<ListItem>
-<Para>
-
-<VariableList>
-<VarListEntry>
-<Term>
- Int32
-</Term>
-<ListItem>
-<Para>
- The size of the packet in bytes.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
- String
-</Term>
-<ListItem>
-<Para>
- The unencrypted password.
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-
-</Para>
-</ListItem>
-</VarListEntry>
-</VariableList>
-</Para>
-
-</Chapter>
+</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</>
+</term>
+<listitem>
+<para>
+ Severity: the field contents are
+ <literal>ERROR</>, <literal>FATAL</>, or
+ <literal>PANIC</> (in an error message), or
+ <literal>WARNING</>, <literal>NOTICE</>, <literal>DEBUG</>,
+ <literal>INFO</>, or <literal>LOG</> (in a notice message),
+ or a localized translation of one of these. Always present.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>C</>
+</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</>
+</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</>
+</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</>
+</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</>
+</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</>
+</term>
+<listitem>
+<para>
+ Internal position: this is defined the same as the <literal>P</>
+ 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</> field will always appear when this field appears.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>q</>
+</term>
+<listitem>
+<para>
+ Internal query: the text of a failed internally-generated command.
+ This could be, for example, a SQL query issued by a PL/pgSQL function.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>W</>
+</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>F</>
+</term>
+<listitem>
+<para>
+ File: the file name of the source-code location where the error
+ was reported.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>L</>
+</term>
+<listitem>
+<para>
+ Line: the line number of the source-code location where the error
+ was reported.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>
+<literal>R</>
+</term>
+<listitem>
+<para>
+ Routine: the name of the source-code routine reporting the error.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<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-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</> field, but given the
+limited width of <literal>options</> 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</>' and '<literal>N</>')
+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</>') 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</> 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>\.</></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</>') 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</>') 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</>') message is no longer generated by
+the backend.
+</para>
+
+<para>
+The NotificationResponse ('<literal>A</>') message has an additional string
+field, which can carry a <quote>payload</> string passed
+from the <command>NOTIFY</command> event sender.
+</para>
+
+<para>
+The EmptyQueryResponse ('<literal>I</>') message used to include an empty
+string parameter; this has been removed.
+</para>
+
+</sect1>
+
+</chapter>