PgProtocol
Wire codec for the PostgreSQL frontend/backend protocol, version 3.0.
The module encodes frontend messages and decodes backend messages. Every
function is pure: bytes in, bytes or plain data out. Nothing here opens a
socket, negotiates TLS, or tracks session state, and nothing here decodes
column values - DataRow fields stay raw bytes for PgTypes to interpret.
Typed messages are a type byte, an int32 length that counts itself but not
the type byte, and a payload. Integers are big-endian and strings are
NUL-terminated UTF-8 unless they are explicitly length-prefixed.
Encoded frames and decoded byte fields are views into pooled buffers that are written once and never rewritten. They stay valid for as long as they are held, but holding one keeps its whole pool buffer alive, so copy anything that has to outlive the message it came from.
Constants
defaultMaxMessageSize
Default maxMessageSize for makeParser: 16 MiB.
Signature
declare const defaultMaxMessageSize: numberConstructors
makeParser
Creates a Parser.
Special pre-startup replies have no type byte and are not handled here; use
decodeSslResponse for those.
Signature
declare function makeParser<A = Uint8Array<ArrayBufferLike> | null>(options?: { readonly maxMessageSize?: number; readonly readField?: FieldReader<A>;}): Parser<A>Decoding
decodeSslResponse
Decodes the single byte the server sends in reply to an SSLRequest. "S"
means the server will speak TLS, "N" means it will not.
Signature
declare function decodeSslResponse(byte: number): Result<"S" | "N", ParseError>Encoding
Encodes any frontend message.
Signature
declare function encode(message: FrontendMessage): Result<Uint8Array<ArrayBufferLike>, EncodeError>encodeCancelRequest
Encodes a CancelRequest. It has no type byte and is sent on a separate
connection, using the pid and secret from BackendKeyData.
Signature
declare function encodeCancelRequest(options: { readonly pid: number; readonly secret: number;}): Uint8ArrayencodeClose
Encodes a Close message.
Signature
declare function encodeClose(options: Omit<Close, "_tag">): Uint8ArrayencodeDescribe
Encodes a Describe message.
Signature
declare function encodeDescribe(options: Omit<Describe, "_tag">): Uint8ArrayencodeExecute
Encodes an Execute message.
Signature
declare function encodeExecute(options: Omit<Execute, "_tag">): Uint8ArrayencodeFlush
Encodes a Flush message.
Signature
declare function encodeFlush(): Uint8ArrayencodePasswordMessage
Encodes a PasswordMessage. The password is sent verbatim, so MD5 hashing
belongs to the caller - see PgAuth.md5Password.
Signature
declare function encodePasswordMessage(options: Omit<PasswordMessage, "_tag">): Uint8ArrayencodeSASLInitialResponse
Encodes a SASLInitialResponse message.
Signature
declare function encodeSASLInitialResponse(options: Omit<SASLInitialResponse, "_tag">): Uint8ArrayencodeSASLResponse
Encodes a SASLResponse message.
Signature
declare function encodeSASLResponse(options: Omit<SASLResponse, "_tag">): Uint8ArrayencodeSslRequest
Encodes an SSLRequest. It has no type byte and is only valid before
startup.
Signature
declare function encodeSslRequest(): Uint8ArrayencodeStartupMessage
Encodes a StartupMessage for protocol 3.0. It has no type byte.
client_encoding defaults to UTF8 because this codec always writes UTF-8.
Signature
declare function encodeStartupMessage(parameters: StartupParameters): Uint8ArrayencodeSync
Encodes a Sync message.
Signature
declare function encodeSync(): Uint8ArrayencodeTerminate
Encodes a Terminate message.
Signature
declare function encodeTerminate(): Uint8ArrayErrors
EncodeError
Error returned when a frontend message cannot be encoded.
Signature
declare class EncodeError extends any { constructor();}ParseError
Error produced when bytes cannot be interpreted as a protocol message.
Signature
declare class ParseError extends any { constructor();}Models
AuthenticationCleartextPassword interface
The server wants the password in the clear.
Signature
interface AuthenticationCleartextPassword { readonly _tag: "AuthenticationCleartextPassword";}AuthenticationMD5Password interface
The server wants an MD5-hashed password, salted with these four bytes.
Signature
interface AuthenticationMD5Password { readonly _tag: "AuthenticationMD5Password"; readonly salt: Uint8Array;}AuthenticationOk interface
Authentication succeeded.
Signature
interface AuthenticationOk { readonly _tag: "AuthenticationOk";}AuthenticationSASL interface
The server offers these SASL mechanisms.
Signature
interface AuthenticationSASL { readonly _tag: "AuthenticationSASL"; readonly mechanisms: readonly Array<string>;}AuthenticationSASLContinue interface
An opaque SASL challenge.
Signature
interface AuthenticationSASLContinue { readonly _tag: "AuthenticationSASLContinue"; readonly data: Uint8Array;}AuthenticationSASLFinal interface
The opaque final SASL payload, carrying the server signature.
Signature
interface AuthenticationSASLFinal { readonly _tag: "AuthenticationSASLFinal"; readonly data: Uint8Array;}AuthenticationUnsupported interface
An authentication request this codec does not model, such as GSSAPI or
SSPI. The method is the raw sub-type integer.
Signature
interface AuthenticationUnsupported { readonly _tag: "AuthenticationUnsupported"; readonly method: number; readonly payload: Uint8Array;}BackendKeyData interface
The identity a CancelRequest needs.
Signature
interface BackendKeyData { readonly _tag: "BackendKeyData"; readonly pid: number; readonly secret: number;}BackendMessage type
Any message the server sends after startup.
Signature
type BackendMessage<A = Uint8Array | null> = AuthenticationOk | AuthenticationCleartextPassword | AuthenticationMD5Password | AuthenticationSASL | AuthenticationSASLContinue | AuthenticationSASLFinal | AuthenticationUnsupported | ParameterStatus | BackendKeyData | ReadyForQuery | RowDescription | DataRow<A> | CommandComplete | EmptyQueryResponse | NoData | ParseComplete | BindComplete | CloseComplete | PortalSuspended | ParameterDescription | ErrorResponse | NoticeResponse | NotificationResponse | NegotiateProtocolVersion | CopyInResponse | CopyOutResponse | CopyBothResponse | CopyData | CopyDone | UnknownBinds parameter values to a prepared statement, creating a portal.
Parameters and results always use the binary format code.
Signature
interface Bind { readonly _tag: "Bind"; readonly parameters: readonly Array<Uint8Array<ArrayBufferLike> | null>; readonly portal: string; readonly statement: string;}BindComplete interface
A Bind succeeded.
Signature
interface BindComplete { readonly _tag: "BindComplete";}Drops a prepared statement or portal.
Signature
interface Close { readonly _tag: "Close"; readonly name: string; readonly target: DescribeTarget;}CloseComplete interface
A Close succeeded.
Signature
interface CloseComplete { readonly _tag: "CloseComplete";}CommandComplete interface
A command finished, reporting its tag such as SELECT 3.
Signature
interface CommandComplete { readonly _tag: "CommandComplete"; readonly commandTag: string;}CopyBothResponse interface
The connection entered bidirectional COPY mode, as used by replication.
Signature
interface CopyBothResponse { readonly _tag: "CopyBothResponse"; readonly columnFormats: readonly Array<number>; readonly format: number;}A chunk of COPY data.
Signature
interface CopyData { readonly _tag: "CopyData"; readonly data: Uint8Array;}The COPY stream ended.
Signature
interface CopyDone { readonly _tag: "CopyDone";}CopyInResponse interface
The server is ready to receive COPY data.
Signature
interface CopyInResponse { readonly _tag: "CopyInResponse"; readonly columnFormats: readonly Array<number>; readonly format: number;}CopyOutResponse interface
The server is about to send COPY data.
Signature
interface CopyOutResponse { readonly _tag: "CopyOutResponse"; readonly columnFormats: readonly Array<number>; readonly format: number;}One result row. Values stay raw bytes; null is SQL NULL. Decoding them
requires the OIDs from the matching RowDescription.
Signature
interface DataRow<out A = Uint8Array | null> { readonly _tag: "DataRow"; readonly values: readonly Array<A>;}Asks for the parameter and row shape of a statement or portal.
Signature
interface Describe { readonly _tag: "Describe"; readonly name: string; readonly target: DescribeTarget;}DescribeTarget type
Which kind of object a Describe or Close message names.
Signature
type DescribeTarget = "statement" | "portal"EmptyQueryResponse interface
The query string was empty.
Signature
interface EmptyQueryResponse { readonly _tag: "EmptyQueryResponse";}ErrorFields interface
The fields of an ErrorResponse or NoticeResponse. Unrecognised field
codes are kept under their raw single-character key.
Signature
interface ErrorFields { [key: string]: string | undefined; readonly code?: string; readonly column?: string; readonly constraint?: string; readonly dataType?: string; readonly detail?: string; readonly file?: string; readonly hint?: string; readonly internalPosition?: string; readonly internalQuery?: string; readonly line?: string; readonly message?: string; readonly position?: string; readonly routine?: string; readonly schema?: string; readonly severity?: string; readonly severityUnlocalized?: string; readonly table?: string; readonly where?: string;}ErrorResponse interface
An error. code is the SQLSTATE.
Signature
interface ErrorResponse { readonly _tag: "ErrorResponse"; readonly fields: ErrorFields;}Runs a portal, optionally limiting the number of rows returned.
Signature
interface Execute { readonly _tag: "Execute"; readonly maxRows: number; readonly portal: string;}FieldDescription interface
One column of a RowDescription.
Signature
interface FieldDescription { readonly columnAttributeNumber: number; readonly dataTypeOid: number; readonly dataTypeSize: number; readonly format: number; readonly name: string; readonly tableOid: number; readonly typeModifier: number;}FieldReader type
Reads one DataRow field out of the parser's buffer, for a parser given a
readField. size is -1 for SQL NULL, and column is the field's position
in the row.
The bytes are the parser's buffer rather than a view of the field, so they
are only the field's for offset to offset + size, and reading outside
that reads the rest of the stream. PgTypes.makeFieldReader is the
implementation for OID-typed columns.
A reader runs inside the stateful parser. If it throws, that failure is
terminal just like a ParseError.
Signature
type FieldReader<A> = (bytes: Uint8Array, offset: number, size: number, column: number) => AAsks the backend to deliver buffered output without ending the transaction.
Signature
interface Flush { readonly _tag: "Flush";}FrontendMessage type
Any message the client sends after startup.
Signature
type FrontendMessage = Parse | Bind | Execute | Describe | Close | Sync | Flush | Terminate | PasswordMessage | SASLInitialResponse | SASLResponseNegotiateProtocolVersion interface
The server speaks an older minor protocol version, or did not recognise some startup options.
Signature
interface NegotiateProtocolVersion { readonly _tag: "NegotiateProtocolVersion"; readonly minorVersion: number; readonly unrecognizedOptions: readonly Array<string>;}The statement or portal returns no rows.
Signature
interface NoData { readonly _tag: "NoData";}NoticeResponse interface
A warning or notice. Same field set as ErrorResponse.
Signature
interface NoticeResponse { readonly _tag: "NoticeResponse"; readonly fields: ErrorFields;}NotificationResponse interface
A LISTEN/NOTIFY message.
Signature
interface NotificationResponse { readonly _tag: "NotificationResponse"; readonly channel: string; readonly payload: string; readonly pid: number;}ParameterDescription interface
The parameter OIDs of a described statement.
Signature
interface ParameterDescription { readonly _tag: "ParameterDescription"; readonly parameterTypes: readonly Array<number>;}ParameterStatus interface
Reports a run-time parameter value, at startup or whenever it changes.
Signature
interface ParameterStatus { readonly _tag: "ParameterStatus"; readonly name: string; readonly value: string;}Prepares a named or unnamed statement.
Signature
interface Parse { readonly _tag: "Parse"; readonly name: string; readonly parameterTypes: readonly Array<number>; readonly query: string;}ParseComplete interface
A Parse succeeded.
Signature
interface ParseComplete { readonly _tag: "ParseComplete";}An incremental decoder for the post-startup backend message stream.
Signature
interface Parser<A = Uint8Array | null> { readonly push: (chunk: Uint8Array) => readonly Array<BackendMessage<A>>; readField: FieldReader<A> | undefined;}PasswordMessage interface
Answers a cleartext or MD5 password request.
Signature
interface PasswordMessage { readonly _tag: "PasswordMessage"; readonly password: string;}PortalSuspended interface
An Execute stopped at its row limit; the portal can be executed again.
Signature
interface PortalSuspended { readonly _tag: "PortalSuspended";}ReadyForQuery interface
The backend is ready for a new query cycle.
Signature
interface ReadyForQuery { readonly _tag: "ReadyForQuery"; readonly status: TransactionStatus;}RowDescription interface
Describes the columns a portal will return.
Signature
interface RowDescription { readonly _tag: "RowDescription"; readonly fields: readonly Array<FieldDescription>;}SASLInitialResponse interface
Selects a SASL mechanism and carries its opaque initial response.
Signature
interface SASLInitialResponse { readonly _tag: "SASLInitialResponse"; readonly initialResponse: Uint8Array<ArrayBufferLike> | null; readonly mechanism: string;}SASLResponse interface
Carries an opaque SASL continuation payload.
Signature
interface SASLResponse { readonly _tag: "SASLResponse"; readonly data: Uint8Array;}StartupParameters interface
Startup parameters. user is required; any other run-time parameter the
server accepts may be passed alongside it.
Signature
interface StartupParameters { [key: string]: string | undefined; readonly application_name?: string; readonly database?: string; readonly user: string;}Closes the current transaction block and requests a ReadyForQuery.
Signature
interface Sync { readonly _tag: "Sync";}Ends the session.
Signature
interface Terminate { readonly _tag: "Terminate";}TransactionStatus type
Transaction status: idle, in a transaction block, or in a failed transaction block.
Signature
type TransactionStatus = "I" | "T" | "E"A message whose type byte this codec does not know. The payload excludes the type byte and the length prefix.
Signature
interface Unknown { readonly _tag: "Unknown"; readonly payload: Uint8Array; readonly type: number;}Where a value writes its wire bytes. Bind frames a parameter by leaving
room for its length, letting the sink fill in the body, and backfilling the
length from what was written, so a value never needs an array of its own.
PgTypes.writeParameter is the implementation for OID-typed values.
Signature
interface ValueSink { readonly beginLength: () => number; readonly bigInt64: (value: bigint) => void; readonly endLength: (token: number) => void; readonly float32: (value: number) => void; readonly float64: (value: number) => void; readonly int16: (value: number) => void; readonly int32: (value: number) => void; readonly raw: (value: Uint8Array) => void; readonly sqlNull: () => void; readonly uint8: (value: number) => void; readonly utf8: (value: string) => void;}Other
Signature
declare function encodeBind(options: Omit<Bind, "_tag">): Result<Uint8Array<ArrayBufferLike>, EncodeError>Signature
declare function encodeParse(options: Omit<Parse, "_tag">): Result<Uint8Array<ArrayBufferLike>, EncodeError>Signature
declare function makeBindEncoder<A, E = never>(writeParameter: (sink: ValueSink, value: A) => Result<void, E>): (options: { readonly parameters: readonly Array<A>; readonly portal: string; readonly statement: string;}) => Result<Uint8Array<ArrayBufferLike>, EncodeError | E>