]> granicus.if.org Git - postgresql/commitdiff
updates for new startup sequence, some reformatting
authorPeter Eisentraut <peter_e@gmx.net>
Fri, 22 Jun 2001 23:27:48 +0000 (23:27 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Fri, 22 Jun 2001 23:27:48 +0000 (23:27 +0000)
doc/src/sgml/protocol.sgml

index e83cf8cbe8a7b192d093aae960a30c34bbbbcbb3..ec35b9c96dfc70851aa37f914abf670c9d803311 100644 (file)
-<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 Phil Thompson (<email>phil@river-bank.demon.co.uk</email>).
-Updates for protocol 2.0 by Tom Lane (<email>tgl@sss.pgh.pa.us</email>).
-</Para>
-</Note>
-</para>
-
-<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> 6.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>
-
-<Para>
-This document describes version 2.0 of the protocol, implemented in
-<ProductName>Postgres</ProductName> 6.4 and later.
-</para>
-
-<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.
-</para>
-
-<Sect1 id="protocol-overview">
-<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>
-
-<Para>
-A frontend sends a start-up 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 <filename>pg_hba.conf</filename>
-file
-to determine what
-further authentication information it requires the frontend to send (if any)
-and responds to the frontend accordingly.
-</para>
-
-<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 start-up (normal case) or failure (for example, an
-invalid database name).
-</para>
-
-<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>
-
-<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>
-
-<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.
-</para>
-</sect1>
-
-<Sect1 id="protocol-protocol">
-<Title>Protocol</Title>
-
-<Para>
-This section describes the message flow.  There are four different types of
-flows depending on the state of the connection:
-start-up, query, function call, and termination.
-There are also special provisions for notification responses and command
-cancellation, which can occur at any time after the start-up phase.
-</para>
-
-
-<Sect2>
-<Title>Start-up</Title>
-
-<Para>
-Start-up is divided into an authentication phase and a backend start-up phase.
-</para>
-
-<Para>
-Initially, the frontend sends a StartupPacket.  The postmaster uses this info
-and the contents of the pg_hba.conf file to determine what authentication
-method the frontend must use.  The postmaster then responds with one of the
-following messages:
-</para>
-
-<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>
-
-<Para>
-After sending AuthenticationOk, the postmaster attempts to launch a backend
-process.  Since this might fail, or the backend might encounter a failure
-during start-up, the frontend must wait for the backend to acknowledge
-successful start-up.  The frontend should send no messages at this point.
-The possible messages from the backend during this phase are:
-
-<VariableList>
-<VarListEntry>
-<Term>
-       BackendKeyData
-</Term>
-<ListItem>
-<Para>
-               This message is issued after successful backend start-up.
-               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 start-up is successful.  The frontend may now issue
-               query or function call messages.
-</Para>
-</ListItem>
-</VarListEntry>
-<VarListEntry>
-<Term>
-       ErrorResponse
-</Term>
-<ListItem>
-<Para>
-               Backend 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 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 start-up phase),
-or to consider ReadyForQuery as ending the start-up phase and each subsequent
-query cycle.
-</para>
-</sect2>
-
-<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>
-
-<Para>
-The possible response messages from the backend are:
-
-<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, i.e., 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>
-
-<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>
-
-<Para>
-Also, if the frontend issues any listen(l) commands then it must be prepared
-to accept NotificationResponse messages at any time; see below.
-</para>
-</sect2>
-
-<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>
-
-<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>
-       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, i.e., 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.
-</para>
-</sect2>
-
-<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>
-
-<Para>
-Notification responses are permitted at any point in the protocol (after
-start-up), 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.
-
-<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.
-</para>
-</sect2>
-
-<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>
-
-<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>
-
-<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
-postmaster signals the backend to abort processing of the current query.
-</para>
-
-<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>
-
-<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 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.
-</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 the
-message, the backend immediately closes the connection and terminates.
-</para>
-
-<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.
-</para>
-</sect2>
-</sect1>
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.18 2001/06/22 23:27:48 petere Exp $ -->
+
+<chapter id="protocol">
+ <title>Frontend/Backend Protocol</title>
+
+ <note>
+  <para>
+   Written by Phil Thompson (<email>phil@river-bank.demon.co.uk</email>).
+   Updates for protocol 2.0 by Tom Lane (<email>tgl@sss.pgh.pa.us</email>).
+  </para>
+ </note>
+
+ <para>
+  <application>PostgreSQL</application> uses a message-based protocol
+  for communication between frontends and backends.  The protocol is
+  implemented over <acronym>TCP/IP</acronym> and also on Unix domain
+  sockets.  <productname>PostgreSQL</productname> 6.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>
+
+ <para>
+  This document describes version 2.0 of the protocol, implemented in
+  <application>PostgreSQL</application> 6.4 and later.
+ </para>
+
+ <para>
+  Higher level features built on this protocol (for example, how
+  <application>libpq</application> passes certain environment
+  variables after the connection is established) are covered
+  elsewhere.
+ </para>
+
+ <sect1 id="protocol-overview">
+  <title>Overview</title>
+
+  <para>
+   A frontend opens a connection to the server and sends a start-up
+   packet.  This includes the names of the user and the database the
+   user wants to connect to.  The server then uses this, and the
+   information in the <filename>pg_hba.conf</filename> file to
+   determine what further authentication information it requires the
+   frontend to send (if any) and responds to the frontend accordingly.
+  </para>
+
+  <para>
+   The frontend then sends any required authentication information.
+   Once the server validates this it responds to the frontend that it
+   is authenticated and sends a message indicating successful start-up
+   (normal case) or failure (for example, an invalid database name).
+  </para>
+
+  <para>
+   In order to serve multiple clients efficiently, the server would
+   normally create a new child process to handle each incoming
+   connection.  However, this is not required.  In the current
+   implementation, a new child process is created immediately after an
+   incoming connection is detected.  In earlier versions of PostgreSQL
+   (7.1 and earlier), the child process was created after sending the
+   authentication confirmation message.
+  </para>
+
+  <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>
+
+  <para>
+   Packets are sent as a data stream.  The first byte determines what
+   should be expected in the rest of the packet.  The exceptions are
+   packets sent as part of the startup and authentication exchange,
+   which comprise a packet length followed by the packet itself.  The
+   difference is historical.
+  </para>
+ </sect1>
+
+ <sect1 id="protocol-protocol">
+  <title>Protocol</title>
+
+  <para>
+   This section describes the message flow.  There are four different
+   types of flows depending on the state of the connection: start-up,
+   query, function call, and termination.  There are also special
+   provisions for notification responses and command cancellation,
+   which can occur at any time after the start-up phase.
+  </para>
+
+  <sect2>
+   <title>Start-up</Title>
+
+   <para>
+    Initially, the frontend sends a StartupPacket.  The server uses
+    this info and the contents of the <filename>pg_hba.conf</filename>
+    file to determine what authentication method the frontend must
+    use.  The server then responds with one of the following messages:
+
+    <variablelist>
+     <varlistentry>
+      <term>ErrorResponse</term>
+      <listitem>
+       <para>
+        The server then immediately closes the connection.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>AuthenticationOk</term>
+      <listitem>
+       <para>
+        The authentication exchange is completed.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>AuthenticationKerberosV4</Term>
+      <listitem>
+       <para>
+        The frontend must then take part in a Kerberos V4
+        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>AuthenticationKerberosV5</Term>
+      <ListItem>
+       <Para>
+        The frontend must then 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>AuthenticationUnencryptedPassword</Term>
+      <ListItem>
+       <Para>
+        The frontend must then send an UnencryptedPasswordPacket.  If
+        this is the correct password, the server 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 server 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 server, then it should immediately close the
+    connection.
+   </para>
+
+   <para>
+    After having received AuthenticationOk, the frontend should wait
+    for further messages from the server.  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>ReadyForQuery</Term>
+      <ListItem>
+       <Para>
+        Start-up is completed.  The frontend may now issue query or
+        function call messages.
+       </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 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 start-up phase), or to consider
+    ReadyForQuery as ending the start-up phase and each subsequent
+    query cycle.
+   </para>
+  </sect2>
+
+  <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>
+
+   <Para>
+    The possible response messages from the backend are:
+
+    <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
+        table.  The frontend should then send a CopyDataRows message.
+        The backend will then respond with a CompletedResponse message
+        with a tag of <literal>COPY</literal>.
+       </Para>
+      </ListItem>
+     </VarListEntry>
+
+     <VarListEntry>
+      <Term>CopyOutResponse</Term>
+      <ListItem>
+       <Para>
+        The backend is ready to copy data from a table to the
+        frontend.  It then sends a CopyDataRows message, and then a
+        CompletedResponse message with a tag of <literal>COPY</literal>.
+       </Para>
+      </ListItem>
+     </VarListEntry>
+
+     <VarListEntry>
+      <Term>CursorResponse</Term>
+      <ListItem>
+       <Para>
+        The query was either an <literal>INSERT</literal>,
+        <literal>UPDATE</literal>, <literal>DELETE</literal>,
+        <literal>FETCH</literal>, or a <literal>SELECT</literal>
+        command.  If the transaction has been aborted then the backend
+        sends a CompletedResponse message with a tag of <literal>*ABORT
+        STATE*</literal>.  Otherwise the following responses are sent.
+       </Para>
+
+       <Para>
+        For an <literal>INSERT</literal> command, the backend then
+        sends a CompletedResponse message with a tag of
+        <literal>INSERT <replaceable>oid</replaceable>
+        <replaceable>rows</replaceable></literal>, 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 <literal>DELETE</literal> command, the backend then
+        sends a CompletedResponse message with a tag of <literal>DELETE
+        <Replaceable>rows</Replaceable></literal> where
+        <Replaceable>rows</Replaceable> is the number of rows deleted.
+       </Para>
+
+       <Para>
+        For an <literal>UPDATE</literal> command, the backend then
+        sends a CompletedResponse message with a tag of <literal>UPDATE
+        <Replaceable>rows</Replaceable></literal> where
+        <Replaceable>rows</Replaceable> is the number of rows affected
+        by the update.
+       </Para>
+
+       <Para>
+        For a <literal>FETCH</literal> or <literal>SELECT</literal>
+        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 <literal>SELECT</literal>.
+       </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, i.e., 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>
+
+   <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 parent process.  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>
+
+   <Para>
+    Also, if the frontend issues any <literal>LISTEN</literal>
+    commands then it must be prepared to accept NotificationResponse
+    messages at any time; see below.
+   </para>
+  </sect2>
+
+  <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>
+
+   <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>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, i.e., 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 <literal>LISTEN</literal>
+    commands then it must be prepared to accept NotificationResponse
+    messages at any time; see below.
+   </para>
+  </sect2>
+
+  <sect2>
+   <title>Notification Responses</title>
+
+   <Para>
+    If a frontend issues a <literal>LISTEN</literal> command, then the
+    backend will send a NotificationResponse message (not to be
+    confused with NoticeResponse!)  whenever a
+    <literal>NOTIFY</literal> command is executed for the same
+    notification name.
+   </para>
+
+   <para>
+    Notification responses are permitted at any point in the protocol
+    (after start-up), 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.
+
+    <VariableList>
+     <VarListEntry>
+      <Term>NotificationResponse</Term>
+      <ListItem>
+       <Para>
+        A <literal>NOTIFY</literal> command has been executed for a
+        name for which a previous <literal>LISTEN</literal> 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.
+   </para>
+  </sect2>
+
+  <Sect2>
+   <Title>Cancelling Requests in Progress</Title>
+
+   <Para>
+    During the processing of a query, the frontend may 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
+    StartupPacket 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 implemenation, this is
+    done by sending a special signal to the backend process that is
+    processing the query.)
+   </para>
+
+   <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>
+
+   <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 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.
+   </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 the message, the backend immediately closes the
+    connection and terminates.
+   </para>
+
+   <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 server if it doesn't want to terminate
+    itself.
+   </para>
+  </sect2>
+ </sect1>
 
 <Sect1 id="protocol-message-types">
 <Title>Message Data Types</Title>
@@ -629,41 +612,41 @@ This section describes the base data types used in messages.
 <VariableList>
 <VarListEntry>
 <Term>
-       Int<Replaceable>n</Replaceable>(<Replaceable>i</Replaceable>)
+        Int<Replaceable>n</Replaceable>(<Replaceable>i</Replaceable>)
 </Term>
 <ListItem>
 <Para>
-               An <Replaceable>n</Replaceable> bit integer in network byte order.
+                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).
+                is the literal value.  Eg. Int16, Int32(42).
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       LimString<Replaceable>n</Replaceable>(<Replaceable>s</Replaceable>)
+        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").
+                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>)
+        String(<Replaceable>s</Replaceable>)
 </Term>
 <ListItem>
 <Para>
-               A conventional C '\0' terminated string with no length
-               limitation.
-               If <Replaceable>s</Replaceable> is specified it is the literal value.
-               Eg. String, String("user").
+                A conventional C '\0' terminated string with no length
+                limitation.
+                If <Replaceable>s</Replaceable> is specified it is the literal value.
+                Eg. String, String("user").
 </Para>
-               
+                
 <Note>
 <Para>
 <Emphasis>There is no predefined limit</Emphasis> on the length of a string
@@ -677,12 +660,12 @@ characters that don't fit into your fixed-size buffer.
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte<Replaceable>n</Replaceable>(<Replaceable>c</Replaceable>)
+        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').
+                Exactly <Replaceable>n</Replaceable> bytes.  If <Replaceable>c</Replaceable> is specified it is the literal
+                value.  Eg. Byte, Byte1('\n').
 </Para>
 </ListItem>
 </VarListEntry>
@@ -695,7 +678,7 @@ characters that don't fit into your fixed-size buffer.
 
 <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).
+by either a frontend (F), a backend (B), or both (F & B).
 </para>
 
 <VariableList>
@@ -708,19 +691,19 @@ AsciiRow (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('D')
+        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.)
+                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>
+        Byte<Replaceable>n</Replaceable>
 </Term>
 <ListItem>
 <Para>
@@ -734,30 +717,30 @@ AsciiRow (B)
                 of the last byte in the bit map is wasted.
 </Para>
 <Para>
-       Then, for each field with a non-NULL value, there is the following:
+        Then, for each field with a non-NULL value, there is the following:
 <VariableList>
 <VarListEntry>
 <Term>
-               Int32
+                Int32
 </Term>
 <ListItem>
 <Para>
-                       Specifies the size of the value of the field, including
-                       this size.
+                        Specifies the size of the value of the field, including
+                        this size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Byte<Replaceable>n</Replaceable>
+                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.
+                        Specifies the value of the field itself in <Acronym>ASCII</Acronym>
+                        characters.  <Replaceable>n</Replaceable> is the above
+                        size minus 4.
                         There is no trailing '\0' in the field data; the front
-                       end must add one if it wants one.
+                        end must add one if it wants one.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -781,21 +764,21 @@ AuthenticationOk (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('R')
+        Byte1('R')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an authentication request.
+                Identifies the message as an authentication request.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(0)
+        Int32(0)
 </Term>
 <ListItem>
 <Para>
-               Specifies that the authentication was successful.
+                Specifies that the authentication was successful.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -814,21 +797,21 @@ AuthenticationKerberosV4 (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('R')
+        Byte1('R')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an authentication request.
+                Identifies the message as an authentication request.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(1)
+        Int32(1)
 </Term>
 <ListItem>
 <Para>
-               Specifies that Kerberos V4 authentication is required.
+                Specifies that Kerberos V4 authentication is required.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -848,21 +831,21 @@ AuthenticationKerberosV5 (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('R')
+        Byte1('R')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an authentication request.
+                Identifies the message as an authentication request.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(2)
+        Int32(2)
 </Term>
 <ListItem>
 <Para>
-               Specifies that Kerberos V5 authentication is required.
+                Specifies that Kerberos V5 authentication is required.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -882,21 +865,21 @@ AuthenticationUnencryptedPassword (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('R')
+        Byte1('R')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an authentication request.
+                Identifies the message as an authentication request.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(3)
+        Int32(3)
 </Term>
 <ListItem>
 <Para>
-               Specifies that an unencrypted password is required.
+                Specifies that an unencrypted password is required.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -916,31 +899,31 @@ AuthenticationEncryptedPassword (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('R')
+        Byte1('R')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an authentication request.
+                Identifies the message as an authentication request.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(4)
+        Int32(4)
 </Term>
 <ListItem>
 <Para>
-               Specifies that an encrypted password is required.
+                Specifies that an encrypted password is required.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte2
+        Byte2
 </Term>
 <ListItem>
 <Para>
-               The salt to use when encrypting the password.
+                The salt to use when encrypting the password.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -959,33 +942,33 @@ BackendKeyData (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('K')
+        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.
+                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
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The process ID of this backend.
+                The process ID of this backend.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The secret key of this backend.
+                The secret key of this backend.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1005,19 +988,19 @@ BinaryRow (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('B')
+        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.)
+                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>
+        Byte<Replaceable>n</Replaceable>
 </Term>
 <ListItem>
 <Para>
@@ -1031,27 +1014,27 @@ BinaryRow (B)
                 of the last byte in the bit map is wasted.
 </Para>
 <Para>
-       Then, for each field with a non-NULL value, there is the following:
+        Then, for each field with a non-NULL value, there is the following:
 <VariableList>
 <VarListEntry>
 <Term>
-               Int32
+                Int32
 </Term>
 <ListItem>
 <Para>
-                       Specifies the size of the value of the field, excluding
-                       this size.
+                        Specifies the size of the value of the field, excluding
+                        this size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Byte<Replaceable>n</Replaceable>
+                Byte<Replaceable>n</Replaceable>
 </Term>
 <ListItem>
 <Para>
-                       Specifies the value of the field itself in binary
-                       format.  <Replaceable>n</Replaceable> is the above size.
+                        Specifies the value of the field itself in binary
+                        format.  <Replaceable>n</Replaceable> is the above size.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1075,44 +1058,44 @@ CancelRequest (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Int32(16)
+        Int32(16)
 </Term>
 <ListItem>
 <Para>
-               The size of the packet in bytes.
+                The size of the packet in bytes.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32(80877102)
+        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.)
+                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
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The process ID of the target backend.
+                The process ID of the target backend.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The secret key for the target backend.
+                The secret key for the target backend.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1132,22 +1115,22 @@ CompletedResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('C')
+        Byte1('C')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a completed response.
+                Identifies the message as a completed response.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The command tag.  This is usually (but not always) a single
-               word that identifies which SQL command was completed.
+                The command tag.  This is usually (but not always) a single
+                word that identifies which SQL command was completed.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1163,9 +1146,9 @@ 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').
+        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>
@@ -1179,12 +1162,12 @@ CopyInResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('G')
+        Byte1('G')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a Start Copy In response.
-               The frontend must now send a CopyDataRows message.
+                Identifies the message as a Start Copy In response.
+                The frontend must now send a CopyDataRows message.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1204,12 +1187,12 @@ CopyOutResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('H')
+        Byte1('H')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a Start Copy Out response.
-               This message will be followed by a CopyDataRows message.
+                Identifies the message as a Start Copy Out response.
+                This message will be followed by a CopyDataRows message.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1229,22 +1212,22 @@ CursorResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('P')
+        Byte1('P')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a cursor response.
+                Identifies the message as a cursor response.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The name of the cursor.  This will be "blank" if the cursor is
-               implicit.
+                The name of the cursor.  This will be "blank" if the cursor is
+                implicit.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1264,21 +1247,21 @@ EmptyQueryResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('I')
+        Byte1('I')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a response to an empty query string.
+                Identifies the message as a response to an empty query string.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String("")
+        String("")
 </Term>
 <ListItem>
 <Para>
-               Unused.
+                Unused.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1298,21 +1281,21 @@ EncryptedPasswordPacket (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The size of the packet in bytes.
+                The size of the packet in bytes.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The encrypted (using crypt()) password.
+                The encrypted (using crypt()) password.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1332,21 +1315,21 @@ ErrorResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('E')
+        Byte1('E')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as an error.
+                Identifies the message as an error.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The error message itself.
+                The error message itself.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1366,65 +1349,65 @@ FunctionCall (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('F')
+        Byte1('F')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a function call.
+                Identifies the message as a function call.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String("")
+        String("")
 </Term>
 <ListItem>
 <Para>
-               Unused.
+                Unused.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               Specifies the object ID of the function to call.
+                Specifies the object ID of the function to call.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               Specifies the number of arguments being supplied to the
-               function.
+                Specifies the number of arguments being supplied to the
+                function.
 </Para>
 <Para>
-       Then, for each argument, there is the following:
+        Then, for each argument, there is the following:
 <VariableList>
 <VarListEntry>
 <Term>
-               Int32
+                Int32
 </Term>
 <ListItem>
 <Para>
-                       Specifies the size of the value of the argument,
-                       excluding this size.
+                        Specifies the size of the value of the argument,
+                        excluding this size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Byte<Replaceable>n</Replaceable>
+                Byte<Replaceable>n</Replaceable>
 </Term>
 <ListItem>
 <Para>
-                       Specifies the value of the field itself in binary
-                       format.  <Replaceable>n</Replaceable> is the above size.
+                        Specifies the value of the field itself in binary
+                        format.  <Replaceable>n</Replaceable> is the above size.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1449,55 +1432,55 @@ FunctionResultResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('V')
+        Byte1('V')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a function call result.
+                Identifies the message as a function call result.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte1('G')
+        Byte1('G')
 </Term>
 <ListItem>
 <Para>
-               Specifies that a nonempty result was returned.
+                Specifies that a nonempty result was returned.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               Specifies the size of the value of the result, excluding this
-               size.
+                Specifies the size of the value of the result, excluding this
+                size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte<Replaceable>n</Replaceable>
+        Byte<Replaceable>n</Replaceable>
 </Term>
 <ListItem>
 <Para>
-               Specifies the value of the result itself in binary format.
-               <Replaceable>n</Replaceable> is the above size.
+                Specifies the value of the result itself in binary format.
+                <Replaceable>n</Replaceable> is the above size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte1('0')
+        Byte1('0')
 </Term>
 <ListItem>
 <Para>
-               Unused.  (Strictly speaking, FunctionResultResponse and
-               FunctionVoidResponse are the same thing but with some optional
-               parts to the message.)
+                Unused.  (Strictly speaking, FunctionResultResponse and
+                FunctionVoidResponse are the same thing but with some optional
+                parts to the message.)
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1517,21 +1500,21 @@ FunctionVoidResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('V')
+        Byte1('V')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a function call result.
+                Identifies the message as a function call result.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Byte1('0')
+        Byte1('0')
 </Term>
 <ListItem>
 <Para>
-               Specifies that an empty result was returned.
+                Specifies that an empty result was returned.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1551,21 +1534,21 @@ NoticeResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('N')
+        Byte1('N')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a notice.
+                Identifies the message as a notice.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The notice message itself.
+                The notice message itself.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1585,31 +1568,31 @@ NotificationResponse (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('A')
+        Byte1('A')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a notification response.
+                Identifies the message as a notification response.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The process ID of the notifying backend process.
+                The process ID of the notifying backend process.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The name of the condition that the notify has been raised on.
+                The name of the condition that the notify has been raised on.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1629,21 +1612,21 @@ Query (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('Q')
+        Byte1('Q')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a query.
+                Identifies the message as a query.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The query string itself.
+                The query string itself.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1663,12 +1646,12 @@ ReadyForQuery (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('Z')
+        Byte1('Z')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message type.  ReadyForQuery is sent
-               whenever the backend is ready for a new query cycle.
+                Identifies the message type.  ReadyForQuery is sent
+                whenever the backend is ready for a new query cycle.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1688,62 +1671,62 @@ RowDescription (B)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('T')
+        Byte1('T')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a row description.
+                Identifies the message as a row description.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int16
+        Int16
 </Term>
 <ListItem>
 <Para>
-               Specifies the number of fields in a row (may be zero).
+                Specifies the number of fields in a row (may be zero).
 </Para>
 <Para>
-       Then, for each field, there is the following:
+        Then, for each field, there is the following:
 <VariableList>
 <VarListEntry>
 <Term>
-               String
+                String
 </Term>
 <ListItem>
 <Para>
-                       Specifies the field name.
+                        Specifies the field name.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Int32
+                Int32
 </Term>
 <ListItem>
 <Para>
-                       Specifies the object ID of the field type.
+                        Specifies the object ID of the field type.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Int16
+                Int16
 </Term>
 <ListItem>
 <Para>
-                       Specifies the type size.
+                        Specifies the type size.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-               Int32
+                Int32
 </Term>
 <ListItem>
 <Para>
-                       Specifies the type modifier.
+                        Specifies the type modifier.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1768,74 +1751,74 @@ StartupPacket (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Int32(296)
+        Int32(296)
 </Term>
 <ListItem>
 <Para>
-               The size of the packet in bytes.
+                The size of the packet in bytes.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       Int32
+        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.
+                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
+        LimString64
 </Term>
 <ListItem>
 <Para>
-               The database name, defaults to the user name if empty.
+                The database name, defaults to the user name if empty.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       LimString32
+        LimString32
 </Term>
 <ListItem>
 <Para>
-               The user name.
+                The user name.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       LimString64
+        LimString64
 </Term>
 <ListItem>
 <Para>
-               Any additional command line arguments to be passed to the
-               backend by the postmaster.
+                Any additional command line arguments to be passed to the
+                backend child process by the server.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       LimString64
+        LimString64
 </Term>
 <ListItem>
 <Para>
-               Unused.
+                Unused.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       LimString64
+        LimString64
 </Term>
 <ListItem>
 <Para>
-               The optional tty the backend should use for debugging messages.
+                The optional tty the backend should use for debugging messages.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1855,11 +1838,11 @@ Terminate (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Byte1('X')
+        Byte1('X')
 </Term>
 <ListItem>
 <Para>
-               Identifies the message as a termination.
+                Identifies the message as a termination.
 </Para>
 </ListItem>
 </VarListEntry>
@@ -1879,21 +1862,21 @@ UnencryptedPasswordPacket (F)
 <VariableList>
 <VarListEntry>
 <Term>
-       Int32
+        Int32
 </Term>
 <ListItem>
 <Para>
-               The size of the packet in bytes.
+                The size of the packet in bytes.
 </Para>
 </ListItem>
 </VarListEntry>
 <VarListEntry>
 <Term>
-       String
+        String
 </Term>
 <ListItem>
 <Para>
-               The unencrypted password.
+                The unencrypted password.
 </Para>
 </ListItem>
 </VarListEntry>