protocol.sgml
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:37k
- <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>
- <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>
- <Para>
- This document describes version 2.0 of the protocol, implemented in
- <ProductName>Postgres</ProductName> v6.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>
- <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 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>
- <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>
- <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>
- <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.
- </para>
- <Sect2>
- <Title>Startup</Title>
- <Para>
- Startup is divided into an authentication phase and a backend startup phase.
- </para>
- <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>
- <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 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:
- <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.
- </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, 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>
- <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, 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.
- </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
- 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.
- <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 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>
- <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>
- <Sect1>
- <Title>Message Data Types</Title>
- <Para>
- This section describes the base data types used in messages.
- <VariableList>
- <VarListEntry>
- <Term>
- Int<Replaceable>n</Replaceable>(<Replaceable>i</Replaceable>)
- </Term>
- <ListItem>
- <Para>
- An <Replaceable>n</Replaceable> bit integer in network byte order.
- 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 ' '
- terminated string. The ' ' 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 ' ' 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>
- <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 (MSB) of the 1st byte, the 2nd
- field corresponds to bit 6 of the 1st byte, the 8th field
- corresponds to bit 0 (LSB) of the 1st byte, the 9th field
- corresponds to bit 7 of the 2nd byte, and so on. Each bit
- is set if the value of the corresponding field is not NULL.
- If the number of fields is not a multiple of 8, the remainder
- 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:
- <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.
- There is no trailing ' ' in the field data; the front
- end must add one if it wants one.
- </Para>
- </ListItem>
- </VarListEntry>
- </VariableList>
- </Para>
- </ListItem>
- </VarListEntry>
- </VariableList>
- </Para>
- </ListItem>
- </VarListEntry>
- <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>
- 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>
- 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 (MSB) of the 1st byte, the 2nd
- field corresponds to bit 6 of the 1st byte, the 8th field
- corresponds to bit 0 (LSB) of the 1st byte, the 9th field
- corresponds to bit 7 of the 2nd byte, and so on. Each bit
- is set if the value of the corresponding field is not NULL.
- If the number of fields is not a multiple of 8, the remainder
- 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:
- <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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- </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>
- 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>
- 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 notifying backend process.
- </Para>
- </ListItem>
- </VarListEntry>
- <VarListEntry>
- <Term>
- String
- </Term>
- <ListItem>
- <Para>
- The name of the condition that the notify has been raised on.
- </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>
- 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>
- 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 (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 empty.
- </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>
- 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>
- </sect1>
- </Chapter>