minato_protocol_backend (minato v0.18.6)
View SourceDecoders for the messages a PostgreSQL server sends to a client.
Internal to minato. The supported surface is minato_protocol.
A payload reaches this module only once every byte of it has arrived, because
the framer in minato_protocol reads the length first and holds a short
message back. A payload that is complete and still does not fit its documented
format raises error({minato_protocol, minato_protocol:report()}).
BackendKeyData is kept
The process ID and secret key a server sends at startup are the whole of what
CancelRequest needs. Discarding them costs nothing at the time and makes
query cancellation impossible for the life of the connection, so they are
decoded and handed on.
Command tags become atoms
CommandComplete carries a tag such as SELECT 5 or CREATE TABLE, and it is
turned into {select, 5} and {create, table}. The atoms are safe to create
from server bytes because the tag vocabulary is compiled into the server: a
tag is chosen from a fixed list by the command that ran, and no query can put a
new word in it.
That argument covers a server behaving as documented and nothing else, so it
does not decide what happens to bytes that are not a tag. A word of more than
255 bytes, or one that is not valid UTF-8, is refused as a malformed message.
Left to binary_to_atom/2 the first would raise system_limit and the second
badarg, which would let whatever is on the far end of the socket choose an
exception outside minato's own shape.
Unrecognised messages
A type byte minato does not model decodes to {unsupported, Type, Payload}.
Every backend message is length prefixed, so an unmodelled one can be stepped
over without the stream losing its place, and a caller that cares can look at
it. An unrecognised ErrorResponse field type is discarded instead, which is
what the protocol documentation asks of a client.
Summary
Functions
-spec decode(byte(), binary()) -> minato_protocol:backend().
Decode one backend message from its type byte and its complete payload.