-
-
-Phil
-Thompson
-
-1998-08-08
-
-
Frontend/Backend Protocol
-
-
-
-
-
-
-
Postgres uses a message-based protocol for communication between frontends
-and backends. The protocol is implemented over
TCP/IP and also on Unix sockets.
-
Postgres 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.
-
-
-This document describes version 2.0 of the protocol, implemented in
-
-
-Higher level features built on this protocol (for example, how libpq passes
-certain environment variables after the connection is established)
-are covered elsewhere.
-
-
-
-
Overview
-
-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.
-
-
-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 pg_hba.conf
-file
-to determine what
-further authentication information it requires the frontend to send (if any)
-and responds to the frontend accordingly.
-
-
-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).
-
-
-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.)
-
-
-When the frontend wishes to disconnect it sends an appropriate packet and
-closes the connection without waiting for a response for the backend.
-
-
-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.
-
-
-
-
-
Protocol
-
-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.
-
-
-
-
-
Start-up
-
-Start-up is divided into an authentication phase and a backend start-up phase.
-
-
-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:
-
-
-
-
-
- ErrorResponse
-
-
- The postmaster then immediately closes the connection.
-
-
-
-
-
- AuthenticationOk
-
-
- The postmaster then hands over to the backend. The postmaster
- takes no further part in the communication.
-
-
-
-
-
- AuthenticationKerberosV4
-
-
- 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.
-
-
-
-
-
- AuthenticationKerberosV5
-
-
- 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.
-
-
-
-
-
- AuthenticationUnencryptedPassword
-
-
- 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.
-
-
-
-
-
- AuthenticationEncryptedPassword
-
-
- 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.
-
-
-
-
-
-
-If the frontend does not support the authentication method requested by the
-postmaster, then it should immediately close the connection.
-
-
-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:
-
-
-
-
- BackendKeyData
-
-
- 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.
-
-
-
-
-
- ReadyForQuery
-
-
- Backend start-up is successful. The frontend may now issue
- query or function call messages.
-
-
-
-
-
- ErrorResponse
-
-
- Backend start-up failed. The connection is closed after
- sending this message.
-
-
-
-
-
- NoticeResponse
-
-
- A warning message has been issued. The frontend should
- display the message but continue listening for ReadyForQuery
- or ErrorResponse.
-
-
-
-
-
-
-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.
-
-
-
-
-
Query
-
-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.
-
-
-The possible response messages from the backend are:
-
-
-
-
- CompletedResponse
-
-
- An SQL command completed normally.
-
-
-
-
-
- CopyInResponse
-
-
- 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".
-
-
-
-
-
- CopyOutResponse
-
-
- 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".
-
-
-
-
-
- CursorResponse
-
-
- 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.
-
- For an insert(l) command, the backend then sends a
- CompletedResponse message with a tag of "INSERT oid rows"
- where rows is the number of rows inserted, and oid is the
- object ID of the inserted row if rows is 1, otherwise oid
- is 0.
-
- For a delete(l) command, the backend then sends a
- CompletedResponse message with a tag of "DELETE rows" where
- rows is the number of rows deleted.
-
- For an update(l) command, the backend then sends a
- CompletedResponse message with a tag of "UPDATE rows" where
- rows is the number of rows deleted.
-
- 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".
-
-
-
-
-
- EmptyQueryResponse
-
-
- An empty query string was recognized. (The need to specially
- distinguish this case is historical.)
-
-
-
-
-
- ErrorResponse
-
-
- An error has occurred.
-
-
-
-
-
- ReadyForQuery
-
-
- 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.
-
-
-
-
-
- NoticeResponse
-
-
- 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.
-
-
-
-
-
-
-A frontend must be prepared to accept ErrorResponse and NoticeResponse
-messages whenever it is expecting any other type of message.
-
-
-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.
-
-
-Also, if the frontend issues any listen(l) commands then it must be prepared
-to accept NotificationResponse messages at any time; see below.
-
-
-
-
-
Function Call
-
-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.
-
-
-The possible response messages from the backend are:
-
-
-
-
- ErrorResponse
-
-
- An error has occurred.
-
-
-
-
-
- FunctionResultResponse
-
-
- The function call was executed and returned a result.
-
-
-
-
-
- FunctionVoidResponse
-
-
- The function call was executed and returned no result.
-
-
-
-
-
- ReadyForQuery
-
-
- Processing of the function call is complete.
- ReadyForQuery will always be sent, whether processing
- terminates successfully or with an error.
-
-
-
-
-
- NoticeResponse
-
-
- 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.
-
-
-
-
-
-
-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.
-
-
-
-
-
Notification Responses
-
-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.
-
-
-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.
-
-
-
-
- NotificationResponse
-
-
- 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.
-
-
-
-
-
-
-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.
-
-
-
-
-
Cancelling Requests in Progress
-
-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.
-
-
-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.
-
-
-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.
-
-
-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.
-
-
-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.
-
-
-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.
-
-
-
-
-
Termination
-
-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.
-
-
-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.
-
-
-
+
+
+
+
Frontend/Backend Protocol
+
+
+
+
+
+
PostgreSQL uses a message-based protocol
+ for communication between frontends and backends. The protocol is
+ implemented over
TCP/IP and also on Unix domain
+ sockets.
PostgreSQL 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.
+
+
+ This document describes version 2.0 of the protocol, implemented in
+
PostgreSQL 6.4 and later.
+
+
+ Higher level features built on this protocol (for example, how
+
libpq passes certain environment
+ variables after the connection is established) are covered
+ elsewhere.
+
+
+
+
Overview
+
+ 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 pg_hba.conf file to
+ determine what further authentication information it requires the
+ frontend to send (if any) and responds to the frontend accordingly.
+
+
+ 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).
+
+
+ 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.
+
+
+ When the frontend wishes to disconnect it sends an appropriate packet and
+ closes the connection without waiting for a response for the backend.
+
+
+ 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.
+
+
+
+
+
Protocol
+
+ 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.
+
+
+
+
Start-up
+
+ Initially, the frontend sends a StartupPacket. The server uses
+ this info and the contents of the pg_hba.conf
+ file to determine what authentication method the frontend must
+ use. The server then responds with one of the following messages:
+
+
+
+ ErrorResponse
+
+ The server then immediately closes the connection.
+
+
+
+
+
+ AuthenticationOk
+
+ The authentication exchange is completed.
+
+
+
+
+
+ AuthenticationKerberosV4
+
+ 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.
+
+
+
+
+
+ AuthenticationKerberosV5
+
+ 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.
+
+
+
+
+
+ AuthenticationUnencryptedPassword
+
+ 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.
+
+
+
+
+
+ AuthenticationEncryptedPassword
+
+ 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.
+
+
+
+
+
+
+
+ If the frontend does not support the authentication method
+ requested by the server, then it should immediately close the
+ connection.
+
+
+ After having received AuthenticationOk, the frontend should wait
+ for further messages from the server. The possible messages from
+ the backend in this phase are:
+
+
+
+ BackendKeyData
+
+ 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.
+
+
+
+
+
+ ReadyForQuery
+
+ Start-up is completed. The frontend may now issue query or
+ function call messages.
+
+
+
+
+
+ ErrorResponse
+
+ Start-up failed. The connection is closed after sending this
+ message.
+
+
+
+
+
+ NoticeResponse
+
+ A warning message has been issued. The frontend should
+ display the message but continue listening for ReadyForQuery
+ or ErrorResponse.
+
+
+
+
+
+
+ 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.
+
+
+
+
+
Query
+
+ 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.
+
+
+ The possible response messages from the backend are:
+
+
+
+ CompletedResponse
+
+ An SQL command completed normally.
+
+
+
+
+
+ CopyInResponse
+
+ 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 COPY.
+
+
+
+
+
+ CopyOutResponse
+
+ 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 COPY.
+
+
+
+
+
+ CursorResponse
+
+ The query was either an INSERT,
+ UPDATE, DELETE,
+ FETCH, or a SELECT
+ 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.
+
+
+ For an INSERT command, the backend then
+ sends a CompletedResponse message with a tag of
+ INSERT oid
+ rows, where
+ rows is the number of rows
+ inserted, and oid is the object ID
+ of the inserted row if rows is 1,
+ otherwise oid is 0.
+
+
+ For a DELETE command, the backend then
+ sends a CompletedResponse message with a tag of DELETE
+ rows where
+ rows is the number of rows deleted.
+
+
+ For an UPDATE command, the backend then
+ sends a CompletedResponse message with a tag of UPDATE
+ rows where
+ rows is the number of rows affected
+ by the update.
+
+
+ For a FETCH or SELECT
+ 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.
+
+
+
+
+
+ EmptyQueryResponse
+
+ An empty query string was recognized. (The need to specially
+ distinguish this case is historical.)
+
+
+
+
+
+ ErrorResponse
+
+ An error has occurred.
+
+
+
+
+
+ ReadyForQuery
+
+ 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.
+
+
+
+
+
+ NoticeResponse
+
+ 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.
+
+
+
+
+
+
+
+ A frontend must be prepared to accept ErrorResponse and
+ NoticeResponse messages whenever it is expecting any other type of
+ message.
+
+
+ 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.
+
+
+ Also, if the frontend issues any LISTEN
+ commands then it must be prepared to accept NotificationResponse
+ messages at any time; see below.
+
+
+
+
+
Function Call
+
+ 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.
+
+
+ The possible response messages from the backend are:
+
+
+
+ ErrorResponse
+
+ An error has occurred.
+
+
+
+
+
+ FunctionResultResponse
+
+ The function call was executed and returned a result.
+
+
+
+
+
+ FunctionVoidResponse
+
+ The function call was executed and returned no result.
+
+
+
+
+
+ ReadyForQuery
+
+ Processing of the function call is complete. ReadyForQuery
+ will always be sent, whether processing terminates
+ successfully or with an error.
+
+
+
+
+
+ NoticeResponse
+
+ 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.
+
+
+
+
+
+
+ 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
+ commands then it must be prepared to accept NotificationResponse
+ messages at any time; see below.
+
+
+
+
+
Notification Responses
+
+ If a frontend issues a LISTEN command, then the
+ backend will send a NotificationResponse message (not to be
+ confused with NoticeResponse!) whenever a
+ NOTIFY command is executed for the same
+ notification name.
+
+
+ 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.
+
+
+
+ NotificationResponse
+
+ A NOTIFY command has been executed for a
+ name for which a previous LISTEN command
+ was executed. Notifications may be sent at any time.
+
+
+
+
+
+
+ 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.
+
+
+
+
+
Cancelling Requests in Progress
+
+ 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.
+
+
+ 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.
+
+
+ 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.)
+
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+
+
+
Termination
+
+ 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.
+
+
+ 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.
+
+
+
Message Data Types
- Intn(i)
+ Intn(i)
- An n bit integer in network byte order.
+ An n bit integer in network byte order.
If i is specified it
- is the literal value. Eg. Int16, Int32(42).
+ is the literal value. Eg. Int16, Int32(42).
- LimStringn(s)
+ LimStringn(s)
- A character array of exactly n bytes interpreted as a '\0'
- terminated string. The '\0' is omitted if there is
- insufficient room. If s is specified it is the literal value.
- Eg. LimString32, LimString64("user").
+ A character array of exactly n bytes interpreted as a '\0'
+ terminated string. The '\0' is omitted if there is
+ insufficient room. If s is specified it is the literal value.
+ Eg. LimString32, LimString64("user").
- String(s)
+ String(s)
- A conventional C '\0' terminated string with no length
- limitation.
- If s is specified it is the literal value.
- Eg. String, String("user").
+ A conventional C '\0' terminated string with no length
+ limitation.
+ If s is specified it is the literal value.
+ Eg. String, String("user").
-
+
There is no predefined limit on the length of a string
- Byten(c)
+ Byten(c)
- Exactly n bytes. If c is specified it is the literal
- value. Eg. Byte, Byte1('\n').
+ Exactly n bytes. If c is specified it is the literal
+ value. Eg. Byte, Byte1('\n').
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).
- Byte1('D')
+ Byte1('D')
- Identifies the message as an
ASCII data row.
- (A prior RowDescription message defines the number of
- fields in the row and their data types.)
+
Identifies the message as an
ASCII data row.
+ (A prior RowDescription message defines the number of
+ fields in the row and their data types.)
- Byten
+ Byten
of the last byte in the bit map is wasted.
- 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:
- Int32
+ Int32
- Specifies the size of the value of the field, including
- this size.
+ Specifies the size of the value of the field, including
+ this size.
- Byten
+ Byten
- Specifies the value of the field itself in
ASCII
- characters. n is the above
- size minus 4.
+
Specifies the value of the field itself in
ASCII
+ characters. n 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.
- Byte1('R')
+ Byte1('R')
- Identifies the message as an authentication request.
+ Identifies the message as an authentication request.
- Int32(0)
+ Int32(0)
- Specifies that the authentication was successful.
+ Specifies that the authentication was successful.
- Byte1('R')
+ Byte1('R')
- Identifies the message as an authentication request.
+ Identifies the message as an authentication request.
- Int32(1)
+ Int32(1)
- Specifies that Kerberos V4 authentication is required.
+ Specifies that Kerberos V4 authentication is required.
- Byte1('R')
+ Byte1('R')
- Identifies the message as an authentication request.
+ Identifies the message as an authentication request.
- Int32(2)
+ Int32(2)
- Specifies that Kerberos V5 authentication is required.
+ Specifies that Kerberos V5 authentication is required.
- Byte1('R')
+ Byte1('R')
- Identifies the message as an authentication request.
+ Identifies the message as an authentication request.
- Int32(3)
+ Int32(3)
- Specifies that an unencrypted password is required.
+ Specifies that an unencrypted password is required.
- Byte1('R')
+ Byte1('R')
- Identifies the message as an authentication request.
+ Identifies the message as an authentication request.
- Int32(4)
+ Int32(4)
- Specifies that an encrypted password is required.
+ Specifies that an encrypted password is required.
- Byte2
+ Byte2
- The salt to use when encrypting the password.
+ The salt to use when encrypting the password.
- Byte1('K')
+ Byte1('K')
- 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.
- Int32
+ Int32
- The process ID of this backend.
+ The process ID of this backend.
- Int32
+ Int32
- The secret key of this backend.
+ The secret key of this backend.
- Byte1('B')
+ Byte1('B')
- 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.)
- Byten
+ Byten
of the last byte in the bit map is wasted.
- 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:
- Int32
+ Int32
- Specifies the size of the value of the field, excluding
- this size.
+ Specifies the size of the value of the field, excluding
+ this size.
- Byten
+ Byten
- Specifies the value of the field itself in binary
- format. n is the above size.
+ Specifies the value of the field itself in binary
+ format. n is the above size.
- Int32(16)
+ Int32(16)
- The size of the packet in bytes.
+ The size of the packet in bytes.
- Int32(80877102)
+ Int32(80877102)
- 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.)
- Int32
+ Int32
- The process ID of the target backend.
+ The process ID of the target backend.
- Int32
+ Int32
- The secret key for the target backend.
+ The secret key for the target backend.
- Byte1('C')
+ Byte1('C')
- Identifies the message as a completed response.
+ Identifies the message as a completed response.
- String
+ String
- 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.
- 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').
- Byte1('G')
+ Byte1('G')
- 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.
- Byte1('H')
+ Byte1('H')
- 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.
- Byte1('P')
+ Byte1('P')
- Identifies the message as a cursor response.
+ Identifies the message as a cursor response.
- String
+ String
- 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.
- Byte1('I')
+ Byte1('I')
- Identifies the message as a response to an empty query string.
+ Identifies the message as a response to an empty query string.
- String("")
+ String("")
- Unused.
+ Unused.
- Int32
+ Int32
- The size of the packet in bytes.
+ The size of the packet in bytes.
- String
+ String
- The encrypted (using crypt()) password.
+ The encrypted (using crypt()) password.
- Byte1('E')
+ Byte1('E')
- Identifies the message as an error.
+ Identifies the message as an error.
- String
+ String
- The error message itself.
+ The error message itself.
- Byte1('F')
+ Byte1('F')
- Identifies the message as a function call.
+ Identifies the message as a function call.
- String("")
+ String("")
- Unused.
+ Unused.
- Int32
+ Int32
- Specifies the object ID of the function to call.
+ Specifies the object ID of the function to call.
- Int32
+ Int32
- Specifies the number of arguments being supplied to the
- function.
+ Specifies the number of arguments being supplied to the
+ function.
- Then, for each argument, there is the following:
+ Then, for each argument, there is the following:
- Int32
+ Int32
- Specifies the size of the value of the argument,
- excluding this size.
+ Specifies the size of the value of the argument,
+ excluding this size.
- Byten
+ Byten
- Specifies the value of the field itself in binary
- format. n is the above size.
+ Specifies the value of the field itself in binary
+ format. n is the above size.
- Byte1('V')
+ Byte1('V')
- Identifies the message as a function call result.
+ Identifies the message as a function call result.
- Byte1('G')
+ Byte1('G')
- Specifies that a nonempty result was returned.
+ Specifies that a nonempty result was returned.
- Int32
+ Int32
- Specifies the size of the value of the result, excluding this
- size.
+ Specifies the size of the value of the result, excluding this
+ size.
- Byten
+ Byten
- Specifies the value of the result itself in binary format.
- n is the above size.
+ Specifies the value of the result itself in binary format.
+ n is the above size.
- Byte1('0')
+ Byte1('0')
- 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.)
- Byte1('V')
+ Byte1('V')
- Identifies the message as a function call result.
+ Identifies the message as a function call result.
- Byte1('0')
+ Byte1('0')
- Specifies that an empty result was returned.
+ Specifies that an empty result was returned.
- Byte1('N')
+ Byte1('N')
- Identifies the message as a notice.
+ Identifies the message as a notice.
- String
+ String
- The notice message itself.
+ The notice message itself.
- Byte1('A')
+ Byte1('A')
- Identifies the message as a notification response.
+ Identifies the message as a notification response.
- Int32
+ Int32
- The process ID of the notifying backend process.
+ The process ID of the notifying backend process.
- String
+ String
- The name of the condition that the notify has been raised on.
+ The name of the condition that the notify has been raised on.
- Byte1('Q')
+ Byte1('Q')
- Identifies the message as a query.
+ Identifies the message as a query.
- String
+ String
- The query string itself.
+ The query string itself.
- Byte1('Z')
+ Byte1('Z')
- 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.
- Byte1('T')
+ Byte1('T')
- Identifies the message as a row description.
+ Identifies the message as a row description.
- Int16
+ Int16
- Specifies the number of fields in a row (may be zero).
+ Specifies the number of fields in a row (may be zero).
- Then, for each field, there is the following:
+ Then, for each field, there is the following:
- String
+ String
- Specifies the field name.
+ Specifies the field name.
- Int32
+ Int32
- Specifies the object ID of the field type.
+ Specifies the object ID of the field type.
- Int16
+ Int16
- Specifies the type size.
+ Specifies the type size.
- Int32
+ Int32
- Specifies the type modifier.
+ Specifies the type modifier.
- Int32(296)
+ Int32(296)
- The size of the packet in bytes.
+ The size of the packet in bytes.
- Int32
+ Int32
- 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.
- LimString64
+ LimString64
- The database name, defaults to the user name if empty.
+ The database name, defaults to the user name if empty.
- LimString32
+ LimString32
- The user name.
+ The user name.
- LimString64
+ LimString64
- 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.
- LimString64
+ LimString64
- Unused.
+ Unused.
- LimString64
+ LimString64
- The optional tty the backend should use for debugging messages.
+ The optional tty the backend should use for debugging messages.
- Byte1('X')
+ Byte1('X')
- Identifies the message as a termination.
+ Identifies the message as a termination.
- Int32
+ Int32
- The size of the packet in bytes.
+ The size of the packet in bytes.
- String
+ String
- The unencrypted password.
+ The unencrypted password.