mirror of
https://github.com/postgres/postgres.git
synced 2025-12-21 05:21:08 +03:00
Allow pg_shadow to be MD5 encrypted. Add ENCRYPTED/UNENCRYPTED option to CREATE/ALTER user. Add password_encryption postgresql.conf option. Update wire protocol version to 2.1.
1892 lines
42 KiB
Plaintext
1892 lines
42 KiB
Plaintext
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.19 2001/08/15 18:42:14 momjian Exp $ -->
|
|
|
|
<chapter id="protocol">
|
|
<title>Frontend/Backend Protocol</title>
|
|
|
|
<note>
|
|
<para>
|
|
Written by Phil Thompson (<email>phil@river-bank.demon.co.uk</email>).
|
|
Updates for protocol 2.0 by Tom Lane (<email>tgl@sss.pgh.pa.us</email>).
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
<application>PostgreSQL</application> uses a message-based protocol
|
|
for communication between frontends and backends. The protocol is
|
|
implemented over <acronym>TCP/IP</acronym> and also on Unix domain
|
|
sockets. <productname>PostgreSQL</productname> 6.3 introduced
|
|
version numbers into the protocol. This was done in such a way as
|
|
to still allow connections from earlier versions of frontends, but
|
|
this document does not cover the protocol used by those earlier
|
|
versions.
|
|
</para>
|
|
|
|
<para>
|
|
This document describes version 2.0 of the protocol, implemented in
|
|
<application>PostgreSQL</application> 6.4 and later.
|
|
</para>
|
|
|
|
<para>
|
|
Higher level features built on this protocol (for example, how
|
|
<application>libpq</application> passes certain environment
|
|
variables after the connection is established) are covered
|
|
elsewhere.
|
|
</para>
|
|
|
|
<sect1 id="protocol-overview">
|
|
<title>Overview</title>
|
|
|
|
<para>
|
|
A frontend opens a connection to the server and sends a start-up
|
|
packet. This includes the names of the user and the database the
|
|
user wants to connect to. The server then uses this, and the
|
|
information in the <filename>pg_hba.conf</filename> file to
|
|
determine what further authentication information it requires the
|
|
frontend to send (if any) and responds to the frontend accordingly.
|
|
</para>
|
|
|
|
<para>
|
|
The frontend then sends any required authentication information.
|
|
Once the server validates this it responds to the frontend that it
|
|
is authenticated and sends a message indicating successful start-up
|
|
(normal case) or failure (for example, an invalid database name).
|
|
</para>
|
|
|
|
<para>
|
|
In order to serve multiple clients efficiently, the server would
|
|
normally create a new child process to handle each incoming
|
|
connection. However, this is not required. In the current
|
|
implementation, a new child process is created immediately after an
|
|
incoming connection is detected. In earlier versions of PostgreSQL
|
|
(7.1 and earlier), the child process was created after sending the
|
|
authentication confirmation message.
|
|
</para>
|
|
|
|
<para>
|
|
When the frontend wishes to disconnect it sends an appropriate packet and
|
|
closes the connection without waiting for a response for the backend.
|
|
</para>
|
|
|
|
<para>
|
|
Packets are sent as a data stream. The first byte determines what
|
|
should be expected in the rest of the packet. The exceptions are
|
|
packets sent as part of the startup and authentication exchange,
|
|
which comprise a packet length followed by the packet itself. The
|
|
difference is historical.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="protocol-protocol">
|
|
<title>Protocol</title>
|
|
|
|
<para>
|
|
This section describes the message flow. There are four different
|
|
types of flows depending on the state of the connection: start-up,
|
|
query, function call, and termination. There are also special
|
|
provisions for notification responses and command cancellation,
|
|
which can occur at any time after the start-up phase.
|
|
</para>
|
|
|
|
<sect2>
|
|
<title>Start-up</Title>
|
|
|
|
<para>
|
|
Initially, the frontend sends a StartupPacket. The server uses
|
|
this info and the contents of the <filename>pg_hba.conf</filename>
|
|
file to determine what authentication method the frontend must
|
|
use. The server then responds with one of the following messages:
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>ErrorResponse</term>
|
|
<listitem>
|
|
<para>
|
|
The server then immediately closes the connection.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>AuthenticationOk</term>
|
|
<listitem>
|
|
<para>
|
|
The authentication exchange is completed.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>AuthenticationKerberosV4</Term>
|
|
<listitem>
|
|
<para>
|
|
The frontend must then take part in a Kerberos V4
|
|
authentication dialog (not described here, part of the
|
|
Kerberos specification) with the server. If this is
|
|
successful, the server responds with an AuthenticationOk,
|
|
otherwise it responds with an ErrorResponse.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<Term>AuthenticationKerberosV5</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then take part in a Kerberos V5
|
|
authentication dialog (not described here, part of the
|
|
Kerberos specification) with the server. If this is
|
|
successful, the server responds with an AuthenticationOk,
|
|
otherwise it responds with an ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>AuthenticationUnencryptedPassword</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then send an UnencryptedPasswordPacket. If
|
|
this is the correct password, the server responds with an
|
|
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>AuthenticationEncryptedPassword</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The frontend must then send an EncryptedPasswordPacket. If
|
|
this is the correct password, the server responds with an
|
|
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<para>
|
|
If the frontend does not support the authentication method
|
|
requested by the server, then it should immediately close the
|
|
connection.
|
|
</para>
|
|
|
|
<para>
|
|
After having received AuthenticationOk, the frontend should wait
|
|
for further messages from the server. The possible messages from
|
|
the backend in this phase are:
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>BackendKeyData</Term>
|
|
<ListItem>
|
|
<Para>
|
|
This message provides secret-key data that the frontend must
|
|
save if it wants to be able to issue cancel requests later.
|
|
The frontend should not respond to this message, but should
|
|
continue listening for a ReadyForQuery message.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>ReadyForQuery</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Start-up is completed. The frontend may now issue query or
|
|
function call messages.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>ErrorResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Start-up failed. The connection is closed after sending this
|
|
message.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>NoticeResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A warning message has been issued. The frontend should
|
|
display the message but continue listening for ReadyForQuery
|
|
or ErrorResponse.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<para>
|
|
The ReadyForQuery message is the same one that the backend will
|
|
issue after each query cycle. Depending on the coding needs of
|
|
the frontend, it is reasonable to consider ReadyForQuery as
|
|
starting a query cycle (and then BackendKeyData indicates
|
|
successful conclusion of the start-up phase), or to consider
|
|
ReadyForQuery as ending the start-up phase and each subsequent
|
|
query cycle.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Query</Title>
|
|
|
|
<Para>
|
|
A Query cycle is initiated by the frontend sending a Query message
|
|
to the backend. The backend then sends one or more response
|
|
messages depending on the contents of the query command string,
|
|
and finally a ReadyForQuery response message. ReadyForQuery
|
|
informs the frontend that it may safely send a new query or
|
|
function call.
|
|
</para>
|
|
|
|
<Para>
|
|
The possible response messages from the backend are:
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>CompletedResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An SQL command completed normally.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>CopyInResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The backend is ready to copy data from the frontend to a
|
|
table. The frontend should then send a CopyDataRows message.
|
|
The backend will then respond with a CompletedResponse message
|
|
with a tag of <literal>COPY</literal>.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>CopyOutResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The backend is ready to copy data from a table to the
|
|
frontend. It then sends a CopyDataRows message, and then a
|
|
CompletedResponse message with a tag of <literal>COPY</literal>.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>CursorResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The query was either an <literal>INSERT</literal>,
|
|
<literal>UPDATE</literal>, <literal>DELETE</literal>,
|
|
<literal>FETCH</literal>, or a <literal>SELECT</literal>
|
|
command. If the transaction has been aborted then the backend
|
|
sends a CompletedResponse message with a tag of <literal>*ABORT
|
|
STATE*</literal>. Otherwise the following responses are sent.
|
|
</Para>
|
|
|
|
<Para>
|
|
For an <literal>INSERT</literal> command, the backend then
|
|
sends a CompletedResponse message with a tag of
|
|
<literal>INSERT <replaceable>oid</replaceable>
|
|
<replaceable>rows</replaceable></literal>, where
|
|
<replaceable>rows</replaceable> is the number of rows
|
|
inserted, and <replaceable>oid</replaceable> is the object ID
|
|
of the inserted row if <Replaceable>rows</Replaceable> is 1,
|
|
otherwise <Replaceable>oid</Replaceable> is 0.
|
|
</Para>
|
|
|
|
<Para>
|
|
For a <literal>DELETE</literal> command, the backend then
|
|
sends a CompletedResponse message with a tag of <literal>DELETE
|
|
<Replaceable>rows</Replaceable></literal> where
|
|
<Replaceable>rows</Replaceable> is the number of rows deleted.
|
|
</Para>
|
|
|
|
<Para>
|
|
For an <literal>UPDATE</literal> command, the backend then
|
|
sends a CompletedResponse message with a tag of <literal>UPDATE
|
|
<Replaceable>rows</Replaceable></literal> where
|
|
<Replaceable>rows</Replaceable> is the number of rows affected
|
|
by the update.
|
|
</Para>
|
|
|
|
<Para>
|
|
For a <literal>FETCH</literal> or <literal>SELECT</literal>
|
|
command, the backend sends a RowDescription message. This is
|
|
then followed by an AsciiRow or BinaryRow message (depending
|
|
on whether a binary cursor was specified) for each row being
|
|
returned to the frontend. Finally, the backend sends a
|
|
CompletedResponse message with a tag of <literal>SELECT</literal>.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>EmptyQueryResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An empty query string was recognized. (The need to specially
|
|
distinguish this case is historical.)
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>ErrorResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An error has occurred.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>ReadyForQuery</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Processing of the query string is complete. A separate
|
|
message is sent to indicate this because the query string may
|
|
contain multiple SQL commands. (CompletedResponse marks the
|
|
end of processing one SQL command, not the whole string.)
|
|
ReadyForQuery will always be sent, whether processing
|
|
terminates successfully or with an error.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>NoticeResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A warning message has been issued in relation to the query.
|
|
Notices are in addition to other responses, i.e., the backend
|
|
will continue processing the command.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<para>
|
|
A frontend must be prepared to accept ErrorResponse and
|
|
NoticeResponse messages whenever it is expecting any other type of
|
|
message.
|
|
</para>
|
|
|
|
<Para>
|
|
Actually, it is possible for NoticeResponse to arrive even when
|
|
the frontend is not expecting any kind of message, that is, the
|
|
backend is nominally idle. (In particular, the backend can be
|
|
commanded to terminate by its parent process. In that case it will
|
|
send a NoticeResponse before closing the connection.) It is
|
|
recommended that the frontend check for such asynchronous notices
|
|
just before issuing any new command.
|
|
</para>
|
|
|
|
<Para>
|
|
Also, if the frontend issues any <literal>LISTEN</literal>
|
|
commands then it must be prepared to accept NotificationResponse
|
|
messages at any time; see below.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Function Call</Title>
|
|
|
|
<Para>
|
|
A Function Call cycle is initiated by the frontend sending a
|
|
FunctionCall message to the backend. The backend then sends one
|
|
or more response messages depending on the results of the function
|
|
call, and finally a ReadyForQuery response message. ReadyForQuery
|
|
informs the frontend that it may safely send a new query or
|
|
function call.
|
|
</para>
|
|
|
|
<Para>
|
|
The possible response messages from the backend are:
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>ErrorResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
An error has occurred.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>FunctionResultResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The function call was executed and returned a result.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>FunctionVoidResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
The function call was executed and returned no result.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>ReadyForQuery</Term>
|
|
<ListItem>
|
|
<Para>
|
|
Processing of the function call is complete. ReadyForQuery
|
|
will always be sent, whether processing terminates
|
|
successfully or with an error.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
<Term>NoticeResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A warning message has been issued in relation to the function
|
|
call. Notices are in addition to other responses, i.e., the
|
|
backend will continue processing the command.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<para>
|
|
A frontend must be prepared to accept ErrorResponse and
|
|
NoticeResponse messages whenever it is expecting any other type of
|
|
message. Also, if it issues any <literal>LISTEN</literal>
|
|
commands then it must be prepared to accept NotificationResponse
|
|
messages at any time; see below.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Notification Responses</title>
|
|
|
|
<Para>
|
|
If a frontend issues a <literal>LISTEN</literal> command, then the
|
|
backend will send a NotificationResponse message (not to be
|
|
confused with NoticeResponse!) whenever a
|
|
<literal>NOTIFY</literal> command is executed for the same
|
|
notification name.
|
|
</para>
|
|
|
|
<para>
|
|
Notification responses are permitted at any point in the protocol
|
|
(after start-up), except within another backend message. Thus,
|
|
the frontend must be prepared to recognize a NotificationResponse
|
|
message whenever it is expecting any message. Indeed, it should
|
|
be able to handle NotificationResponse messages even when it is
|
|
not engaged in a query.
|
|
|
|
<VariableList>
|
|
<VarListEntry>
|
|
<Term>NotificationResponse</Term>
|
|
<ListItem>
|
|
<Para>
|
|
A <literal>NOTIFY</literal> command has been executed for a
|
|
name for which a previous <literal>LISTEN</literal> command
|
|
was executed. Notifications may be sent at any time.
|
|
</Para>
|
|
</ListItem>
|
|
</VarListEntry>
|
|
</VariableList>
|
|
</Para>
|
|
|
|
<para>
|
|
It may be worth pointing out that the names used in listen and
|
|
notify commands need not have anything to do with names of
|
|
relations (tables) in the SQL database. Notification names are
|
|
simply arbitrarily chosen condition names.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Cancelling Requests in Progress</Title>
|
|
|
|
<Para>
|
|
During the processing of a query, the frontend may request
|
|
cancellation of the query. The cancel request is not sent
|
|
directly on the open connection to the backend for reasons of
|
|
implementation efficiency: we don't want to have the backend
|
|
constantly checking for new input from the frontend during query
|
|
processing. Cancel requests should be relatively infrequent, so
|
|
we make them slightly cumbersome in order to avoid a penalty in
|
|
the normal case.
|
|
</para>
|
|
|
|
<Para>
|
|
To issue a cancel request, the frontend opens a new connection to
|
|
the server and sends a CancelRequest message, rather than the
|
|
StartupPacket message that would ordinarily be sent across a new
|
|
connection. The server will process this request and then close
|
|
the connection. For security reasons, no direct reply is made to
|
|
the cancel request message.
|
|
</para>
|
|
|
|
<Para>
|
|
A CancelRequest message will be ignored unless it contains the
|
|
same key data (PID and secret key) passed to the frontend during
|
|
connection start-up. If the request matches the PID and secret
|
|
key for a currently executing backend, the processing of the
|
|
current query is aborted. (In the existing implemenation, this is
|
|
done by sending a special signal to the backend process that is
|
|
processing the query.)
|
|
</para>
|
|
|
|
<Para>
|
|
The cancellation signal may or may not have any effect --- for
|
|
example, if it arrives after the backend has finished processing
|
|
the query, then it will have no effect. If the cancellation is
|
|
effective, it results in the current command being terminated
|
|
early with an error message.
|
|
</para>
|
|
|
|
<Para>
|
|
The upshot of all this is that for reasons of both security and
|
|
efficiency, the frontend has no direct way to tell whether a
|
|
cancel request has succeeded. It must continue to wait for the
|
|
backend to respond to the query. Issuing a cancel simply improves
|
|
the odds that the current query will finish soon, and improves the
|
|
odds that it will fail with an error message instead of
|
|
succeeding.
|
|
</para>
|
|
|
|
<Para>
|
|
Since the cancel request is sent across a new connection to the
|
|
server and not across the regular frontend/backend communication
|
|
link, it is possible for the cancel request to be issued by any
|
|
process, not just the frontend whose query is to be canceled.
|
|
This may have some benefits of flexibility in building
|
|
multiple-process applications. It also introduces a security
|
|
risk, in that unauthorized persons might try to cancel queries.
|
|
The security risk is addressed by requiring a dynamically
|
|
generated secret key to be supplied in cancel requests.
|
|
</para>
|
|
</sect2>
|
|
|
|
<Sect2>
|
|
<Title>Termination</Title>
|
|
|
|
<Para>
|
|
The normal, graceful termination procedure is that the frontend
|
|
sends a Terminate message and immediately closes the connection.
|
|
On receipt of the message, the backend immediately closes the
|
|
connection and terminates.
|
|
</para>
|
|
|
|
<Para>
|
|
An ungraceful termination may occur due to software failure (i.e.,
|
|
core dump) at either end. If either frontend or backend sees an
|
|
unexpected closure of the connection, it should clean up and
|
|
terminate. The frontend has the option of launching a new backend
|
|
by recontacting the server if it doesn't want to terminate
|
|
itself.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<Sect1 id="protocol-message-types">
|
|
<Title>Message Data Types</Title>
|
|
|
|
<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 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 MD5 or 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 child process by the server.
|
|
</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>
|