This section provides a quick checklist of changes, for the
benefit of developers trying to update existing client libraries
to protocol 3.0.

The initial startup packet uses a flexible list-of-strings
format instead of a fixed format. Notice that session default
values for run-time parameters can now be specified directly in
the startup packet. (Actually, you could do that before using the
options field, but given the limited
width of options and the lack of any way
to quote whitespace in the values, it wasn't a very safe
technique.)

All messages now have a length count immediately following the
message type byte (except for startup packets, which have no type
byte). Also note that PasswordMessage now has a type byte.

ErrorResponse and NoticeResponse ('E'
and 'N') messages now contain multiple
fields, from which the client code may assemble an error message
of the desired level of verbosity. Note that individual fields
will typically not end with a newline, whereas the single string
sent in the older protocol always did.

The ReadyForQuery ('Z') message
includes a transaction status indicator.

The distinction between BinaryRow and DataRow message types is
gone; the single DataRow message type serves for returning data
in all formats. Note that the layout of DataRow has changed to
make it easier to parse. Also, the representation of binary
values has changed: it is no longer directly tied to the server's
internal representation.

There is a new "extended query"
sub-protocol, which adds the frontend message types Parse, Bind,
Execute, Describe, Close, Flush, and Sync, and the backend
message types ParseComplete, BindComplete, PortalSuspended,
ParameterDescription, NoData, and CloseComplete. Existing clients
do not have to concern themselves with this sub-protocol, but
making use of it may allow improvements in performance or
functionality.

COPY data is now encapsulated into
CopyData and CopyDone messages. There is a well-defined way to
recover from errors during COPY. The
special "\."
last line is not needed anymore, and is not sent during
COPY OUT. (It is still recognized as a
terminator during COPY IN, but its use
is deprecated and will eventually be removed.) Binary COPY is supported. The CopyInResponse and
CopyOutResponse messages include fields indicating the number of
columns and the format of each column.

The layout of FunctionCall and FunctionCallResponse messages
has changed. FunctionCall can now support passing NULL arguments
to functions. It also can handle passing parameters and
retrieving results in either text or binary format. There is no
longer any reason to consider FunctionCall a potential security
hole, since it does not offer direct access to internal server
data representations.

The backend sends ParameterStatus ('S') messages during connection startup for all
parameters it considers interesting to the client library.
Subsequently, a ParameterStatus message is sent whenever the
active value changes for any of these parameters.

The RowDescription ('T') message
carries new table OID and column number fields for each column of
the described row. It also shows the format code for each
column.

The CursorResponse ('P') message is
no longer generated by the backend.

The NotificationResponse ('A')
message has an additional string field, which is presently empty
but may someday carry additional data passed from the NOTIFY event sender.

The EmptyQueryResponse ('I') message
used to include an empty string parameter; this has been
removed.