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 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.

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
oidrows" 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.

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.

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.

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.

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.