mirror of
https://github.com/postgres/postgres.git
synced 2025-06-04 00:02:37 -04:00
1909 lines
37 KiB
Plaintext
1909 lines
37 KiB
Plaintext
<Chapter Id="protocol">
|
|
<DocInfo>
|
|
<Author>
|
|
<FirstName>Phil</FirstName>
|
|
<Surname>Thompson</Surname>
|
|
</Author>
|
|
<Date>1998-08-08</Date>
|
|
</DocInfo>
|
|
<Title>Frontend/Backend Protocol</Title>
|
|
|
|
<Para>
|
|
<Note>
|
|
<Para>
|
|
Written by Phil Thompson (<email>phil@river-bank.demon.co.uk</email>).
|
|
Updates for protocol 2.0 by Tom Lane (<email>tgl@sss.pgh.pa.us</email>).
|
|
</Para>
|
|
</Note>
|
|
</para>
|
|
|
|
<Para>
|
|
<ProductName>Postgres</ProductName> uses a message-based protocol for communication between frontends
|
|
and backends. The protocol is implemented over <Acronym>TCP/IP</Acronym> and also on Unix sockets.
|
|
<ProductName>Postgres</ProductName> 6.3 introduced version numbers into the protocol.
|
|
This was done in such
|
|
a way as to still allow connections from earlier versions of frontends, but
|
|
this document does not cover the protocol used by those earlier versions.
|
|
</para>
|
|
|
|
<Para>
|
|
This document describes version 2.0 of the protocol, implemented in
|
|
<ProductName>Postgres</ProductName> 6.4 and later.
|
|
</para>
|
|
|
|
<Para>
|
|
Higher level features built on this protocol (for example, how <FileName>libpq</FileName> passes
|
|
certain environment variables after the connection is established)
|
|
are covered elsewhere.
|
|
</para>
|
|
|
|
<Sect1 id="protocol-overview">
|
|
<Title>Overview</Title>
|
|
|
|
<Para>
|
|
The three major components are the frontend (running on the client) and the
|
|
postmaster and backend (running on the server). The postmaster and backend
|
|
have different roles but may be implemented by the same executable.
|
|
</para>
|
|
|
|
<Para>
|
|
A frontend sends a start-up packet to the postmaster. This includes the names
|
|
of the user and the database the user wants to connect to. The postmaster then
|
|
uses this, and the information in the <filename>pg_hba.conf</filename>
|
|
file
|
|
to determine what
|
|
further authentication information it requires the frontend to send (if any)
|
|
and responds to the frontend accordingly.
|
|
</para>
|
|
|
|
<Para>
|
|
The frontend then sends any required authentication information. Once the
|
|
postmaster validates this it responds to the frontend that it is authenticated
|
|
and hands over the connection to a backend. The backend then sends a message
|
|
indicating successful start-up (normal case) or failure (for example, an
|
|
invalid database name).
|
|
</para>
|
|
|
|
<Para>
|
|
Subsequent communications are query and result packets exchanged between the
|
|
frontend and the backend. The postmaster takes no further part in ordinary
|
|
query/result communication. (However, the postmaster is involved when the
|
|
frontend wishes to cancel a query currently being executed by its backend.
|
|
Further details about that appear below.)
|
|
</para>
|
|
|
|
<Para>
|
|
When the frontend wishes to disconnect it sends an appropriate packet and
|
|
closes the connection without waiting for a response for the backend.
|
|
</para>
|
|
|
|
<Para>
|
|
Packets are sent as a data stream. The first byte determines what should be
|
|
expected in the rest of the packet. The exception is packets sent from a
|
|
frontend to the postmaster, which comprise a packet length then the packet
|
|
itself. The difference is historical.
|
|
</para>
|
|
</sect1>
|
|
|
|
<Sect1 id="protocol-protocol">
|
|
<Title>Protocol</Title>
|
|
|
|
<Para>
|
|
This section describes the message flow. There are four different types of
|
|
flows depending on the state of the connection:
|
|
start-up, query, function call, and termination.
|
|
There are also special provisions for notification responses and command
|
|
cancellation, which can occur at any time after the start-up phase.
|
|
</para>
|
|
|
|
|
|
<Sect2>
|
|
<Title>Start-up</Title>
|
|
|
|
<Para>
|
|
Start-up is divided into an authentication phase and a backend start-up phase.
|
|
</para>
|
|
|
|
<Para>
|
|
Initially, the frontend sends a StartupPacket. The postmaster uses this info
|
|
and the contents of the pg_hba.conf file to determine what authentication
|
|
method the frontend must use. The postmaster then responds with one of the
|
|
following messages:
|
|
</para>
|
|
|
|
<Para>
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>
|
|
ErrorResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The postmaster then immediately closes the connection.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
AuthenticationOk
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The postmaster then hands over to the backend. The postmaster
|
|
takes no further part in the communication.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
AuthenticationKerberosV4
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then take part in a Kerberos V4
|
|
authentication dialog (not described here) with the postmaster.
|
|
If this is successful, the postmaster responds with an
|
|
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
AuthenticationKerberosV5
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then take part in a Kerberos V5
|
|
authentication dialog (not described here) with the postmaster.
|
|
If this is successful, the postmaster responds with an
|
|
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
AuthenticationUnencryptedPassword
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then send an UnencryptedPasswordPacket.
|
|
If this is the correct password, the postmaster responds with
|
|
an AuthenticationOk, otherwise it responds with an
|
|
ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
AuthenticationEncryptedPassword
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then send an EncryptedPasswordPacket.
|
|
If this is the correct password, the postmaster responds with
|
|
an AuthenticationOk, otherwise it responds with an
|
|
ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<Para>
|
|
If the frontend does not support the authentication method requested by the
|
|
postmaster, then it should immediately close the connection.
|
|
</para>
|
|
|
|
<Para>
|
|
After sending AuthenticationOk, the postmaster attempts to launch a backend
|
|
process. Since this might fail, or the backend might encounter a failure
|
|
during start-up, the frontend must wait for the backend to acknowledge
|
|
successful start-up. The frontend should send no messages at this point.
|
|
The possible messages from the backend during this phase are:
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>
|
|
BackendKeyData
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
This message is issued after successful backend start-up.
|
|
It provides secret-key data that the frontend must save
|
|
if it wants to be able to issue cancel requests later.
|
|
The frontend should not respond to this message, but should
|
|
continue listening for a ReadyForQuery message.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
ReadyForQuery
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Backend start-up is successful. The frontend may now issue
|
|
query or function call messages.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
ErrorResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Backend start-up failed. The connection is closed after
|
|
sending this message.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
NoticeResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A warning message has been issued. The frontend should
|
|
display the message but continue listening for ReadyForQuery
|
|
or ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<Para>
|
|
The ReadyForQuery message is the same one that the backend will issue after
|
|
each query cycle. Depending on the coding needs of the frontend, it is
|
|
reasonable to consider ReadyForQuery as starting a query cycle (and then
|
|
BackendKeyData indicates successful conclusion of the start-up phase),
|
|
or to consider ReadyForQuery as ending the start-up phase and each subsequent
|
|
query cycle.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Query</Title>
|
|
|
|
<Para>
|
|
A Query cycle is initiated by the frontend sending a Query message to the
|
|
backend. The backend then sends one or more response messages depending
|
|
on the contents of the query command string, and finally a ReadyForQuery
|
|
response message. ReadyForQuery informs the frontend that it may safely
|
|
send a new query or function call.
|
|
</para>
|
|
|
|
<Para>
|
|
The possible response messages from the backend are:
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>
|
|
CompletedResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An SQL command completed normally.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
CopyInResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The backend is ready to copy data from the frontend to a
|
|
relation. The frontend should then send a CopyDataRows
|
|
message. The backend will then respond with a
|
|
CompletedResponse message with a tag of "COPY".
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
CopyOutResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The backend is ready to copy data from a relation to the
|
|
frontend. It then sends a CopyDataRows message, and then a
|
|
CompletedResponse message with a tag of "COPY".
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
CursorResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The query was either an insert(l), delete(l), update(l),
|
|
fetch(l) or a select(l) command.
|
|
If the transaction has been
|
|
aborted then the backend sends a CompletedResponse message with
|
|
a tag of "*ABORT STATE*". Otherwise the following responses
|
|
are sent.
|
|
</Para>
|
|
<Para>
|
|
For an insert(l) command, the backend then sends a
|
|
CompletedResponse message with a tag of "INSERT <Replaceable>oid</Replaceable> <Replaceable>rows</Replaceable>"
|
|
where <Replaceable>rows</Replaceable> is the number of rows inserted, and <Replaceable>oid</Replaceable> is the
|
|
object ID of the inserted row if <Replaceable>rows</Replaceable> is 1, otherwise <Replaceable>oid</Replaceable>
|
|
is 0.
|
|
</Para>
|
|
<Para>
|
|
For a delete(l) command, the backend then sends a
|
|
CompletedResponse message with a tag of "DELETE <Replaceable>rows</Replaceable>" where
|
|
<Replaceable>rows</Replaceable> is the number of rows deleted.
|
|
</Para>
|
|
<Para>
|
|
For an update(l) command, the backend then sends a
|
|
CompletedResponse message with a tag of "UPDATE <Replaceable>rows</Replaceable>" where
|
|
<Replaceable>rows</Replaceable> is the number of rows deleted.
|
|
</Para>
|
|
<Para>
|
|
For a fetch(l) or select(l) command, the backend sends a
|
|
RowDescription message. This is then followed by an AsciiRow
|
|
or BinaryRow message (depending on whether a binary cursor was
|
|
specified) for each row being returned to the frontend.
|
|
Finally, the backend sends a CompletedResponse message with a
|
|
tag of "SELECT".
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
EmptyQueryResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An empty query string was recognized. (The need to specially
|
|
distinguish this case is historical.)
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
ErrorResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An error has occurred.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
ReadyForQuery
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Processing of the query string is complete. A separate
|
|
message is sent to indicate this because the query string
|
|
may contain multiple SQL commands. (CompletedResponse marks
|
|
the end of processing one SQL command, not the whole string.)
|
|
ReadyForQuery will always be sent, whether processing
|
|
terminates successfully or with an error.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
NoticeResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A warning message has been issued in relation to the query.
|
|
Notices are in addition to other responses, 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
|
|
start-up), except within another backend message. Thus, the frontend
|
|
must be prepared to recognize a NotificationResponse message whenever it is
|
|
expecting any message. Indeed, it should be able to handle
|
|
NotificationResponse messages even when it is not engaged in a query.
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>
|
|
NotificationResponse
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A notify(l) command has been executed for a name for which
|
|
a previous listen(l) command was executed. Notifications
|
|
may be sent at any time.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<Para>
|
|
It may be worth pointing out that the names used in listen and notify
|
|
commands need not have anything to do with names of relations (tables)
|
|
in the SQL database. Notification names are simply arbitrarily chosen
|
|
condition names.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Cancelling Requests in Progress</Title>
|
|
|
|
<Para>
|
|
During the processing of a query, the frontend may request cancellation of the
|
|
query by sending an appropriate request to the postmaster. The cancel request
|
|
is not sent directly to the backend for reasons of implementation efficiency:
|
|
we don't want to have the backend constantly checking for new input from
|
|
the frontend during query processing. Cancel requests should be relatively
|
|
infrequent, so we make them slightly cumbersome in order to avoid a penalty
|
|
in the normal case.
|
|
</para>
|
|
|
|
<Para>
|
|
To issue a cancel request, the frontend opens a new connection to the
|
|
postmaster and sends a CancelRequest message, rather than the StartupPacket
|
|
message that would ordinarily be sent across a new connection. The postmaster
|
|
will process this request and then close the connection. For security
|
|
reasons, no direct reply is made to the cancel request message.
|
|
</para>
|
|
|
|
<Para>
|
|
A CancelRequest message will be ignored unless it contains the same key data
|
|
(PID and secret key) passed to the frontend during connection start-up. If the
|
|
request matches the PID and secret key for a currently executing backend, the
|
|
postmaster signals the backend to abort processing of the current query.
|
|
</para>
|
|
|
|
<Para>
|
|
The cancellation signal may or may not have any effect --- for example, if it
|
|
arrives after the backend has finished processing the query, then it will have
|
|
no effect. If the cancellation is effective, it results in the current
|
|
command being terminated early with an error message.
|
|
</para>
|
|
|
|
<Para>
|
|
The upshot of all this is that for reasons of both security and efficiency,
|
|
the frontend has no direct way to tell whether a cancel request has succeeded.
|
|
It must continue to wait for the backend to respond to the query. Issuing a
|
|
cancel simply improves the odds that the current query will finish soon,
|
|
and improves the odds that it will fail with an error message instead of
|
|
succeeding.
|
|
</para>
|
|
|
|
<Para>
|
|
Since the cancel request is sent to the postmaster and not across the
|
|
regular frontend/backend communication link, it is possible for the cancel
|
|
request to be issued by any process, not just the frontend whose query is
|
|
to be canceled. This may have some benefits of flexibility in building
|
|
multiple-process applications. It also introduces a security risk, in that
|
|
unauthorized persons might try to cancel queries. The security risk is
|
|
addressed by requiring a dynamically generated secret key to be supplied
|
|
in cancel requests.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Termination</Title>
|
|
|
|
<Para>
|
|
The normal, graceful termination procedure is that the frontend sends a
|
|
Terminate message and immediately closes the connection. On receipt of the
|
|
message, the backend immediately closes the connection and terminates.
|
|
</para>
|
|
|
|
<Para>
|
|
An ungraceful termination may occur due to software failure (i.e., core dump)
|
|
at either end. If either frontend or backend sees an unexpected closure of
|
|
the connection, it should clean up and terminate. The frontend has the option
|
|
of launching a new backend by recontacting the postmaster, if it doesn't want
|
|
to terminate itself.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<Sect1 id="protocol-message-types">
|
|
<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 '\0'
|
|
terminated string. The '\0' is omitted if there is
|
|
insufficient room. If <Replaceable>s</Replaceable> is specified it is the literal value.
|
|
Eg. LimString32, LimString64("user").
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
String(<Replaceable>s</Replaceable>)
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A conventional C '\0' terminated string with no length
|
|
limitation.
|
|
If <Replaceable>s</Replaceable> is specified it is the literal value.
|
|
Eg. String, String("user").
|
|
</Para>
|
|
|
|
<Note>
|
|
<Para>
|
|
<Emphasis>There is no predefined limit</Emphasis> on the length of a string
|
|
that can be returned by the backend. Good coding strategy for a frontend
|
|
is to use an expandable buffer so that anything that fits in memory can be
|
|
accepted. If that's not feasible, read the full string and discard trailing
|
|
characters that don't fit into your fixed-size buffer.
|
|
</Para>
|
|
</Note>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
<VarListEntry>
|
|
<Term>
|
|
Byte<Replaceable>n</Replaceable>(<Replaceable>c</Replaceable>)
|
|
</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Exactly <Replaceable>n</Replaceable> bytes. If <Replaceable>c</Replaceable> is specified it is the literal
|
|
value. Eg. Byte, Byte1('\n').
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
</sect1>
|
|
|
|
<Sect1 id="protocol-message-formats">
|
|
<Title>Message Formats</Title>
|
|
|
|
<Para>
|
|
This section describes the detailed format of each message. Each 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 '\0' 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>
|