Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

PgProtocol unstable

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.

72 exports Since v4.0.0 Source

Constants

Since v4.0.0

Default maxMessageSize for makeParser: 16 MiB.

Signature

declare const defaultMaxMessageSize: number

Constructors

makeParser

unstable
Since v4.0.0

Creates a Parser.

Details

Special pre-startup replies have no type byte. Use decodeSslResponse for those replies.

Signature

declare function makeParser<A = Uint8Array<ArrayBufferLike> | null>(options?: {
readonly maxMessageSize?: number;
readonly readField?: FieldReader<A>;
}): Parser<A>

Decoding

Since v4.0.0

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

encode

unstable
Since v4.0.0

Encodes any frontend message.

Signature

declare function encode(message: FrontendMessage): Result<Uint8Array<ArrayBufferLike>, EncodeError>

encodeBind

unstable
Since v4.0.0

Encodes a Bind message.

Signature

declare function encodeBind(options: Omit<Bind, "_tag">): Result<Uint8Array<ArrayBufferLike>, EncodeError>
Since v4.0.0

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;
}): Uint8Array

encodeClose

unstable
Since v4.0.0

Encodes a Close message.

Signature

declare function encodeClose(options: Omit<Close, "_tag">): Uint8Array
Since v4.0.0

Encodes a Describe message.

Signature

declare function encodeDescribe(options: Omit<Describe, "_tag">): Uint8Array
Since v4.0.0

Encodes an Execute message.

Signature

declare function encodeExecute(options: Omit<Execute, "_tag">): Uint8Array

encodeFlush

unstable
Since v4.0.0

Encodes a Flush message.

Signature

declare function encodeFlush(): Uint8Array

encodeParse

unstable
Since v4.0.0

Encodes a Parse message.

Signature

declare function encodeParse(options: Omit<Parse, "_tag">): Result<Uint8Array<ArrayBufferLike>, EncodeError>
Since v4.0.0

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">): Uint8Array

Encodes a SASLInitialResponse message.

Signature

declare function encodeSASLInitialResponse(options: Omit<SASLInitialResponse, "_tag">): Uint8Array
Since v4.0.0

Encodes a SASLResponse message.

Signature

declare function encodeSASLResponse(options: Omit<SASLResponse, "_tag">): Uint8Array
Since v4.0.0

Encodes an SSLRequest. It has no type byte and is only valid before startup.

Signature

declare function encodeSslRequest(): Uint8Array
Since v4.0.0

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): Uint8Array

encodeSync

unstable
Since v4.0.0

Encodes a Sync message.

Signature

declare function encodeSync(): Uint8Array
Since v4.0.0

Encodes a Terminate message.

Signature

declare function encodeTerminate(): Uint8Array
Since v4.0.0

Creates a Bind encoder that writes parameters directly into the frame.

Details

textFormat identifies parameters encoded as text. All other parameters use the binary format.

Signature

declare function makeBindEncoder<A, E = never>(writeParameter: (sink: ValueSink, value: A) => Result<void, E>, textFormat?: (value: A) => boolean): (options: {
readonly parameters: readonly Array<A>;
readonly portal: string;
readonly statement: string;
}) => Result<Uint8Array<ArrayBufferLike>, EncodeError | E>

Example

import { PgProtocol, PgTypes } from "@effect/sql-pg"
const encodeBind = PgProtocol.makeBindEncoder(PgTypes.writeParameter, PgTypes.isTextFormat)
const frame = encodeBind({ portal: "", statement: "s1", parameters: [PgTypes.int4(1)] })

Errors

EncodeError

unstable
Since v4.0.0

Error returned when a frontend message cannot be encoded.

Signature

declare class EncodeError extends YieldableError<this> & {
readonly _tag: "PgProtocolEncodeError";
} & Readonly<{
readonly message: string;
}> {
constructor(args: {
readonly message: string;
});
}

ParseError

unstable
Since v4.0.0

Error produced when bytes cannot be interpreted as a protocol message.

Signature

declare class ParseError extends YieldableError<this> & {
readonly _tag: "PgProtocolParseError";
} & Readonly<{
readonly message: string;
}> {
constructor(args: {
readonly message: string;
});
}

Models

Since v4.0.0

The server wants the password in the clear.

Signature

interface AuthenticationCleartextPassword {
readonly _tag: "AuthenticationCleartextPassword";
}

AuthenticationMD5Password

interface unstable
Since v4.0.0

The server wants an MD5-hashed password, salted with these four bytes.

Signature

interface AuthenticationMD5Password {
readonly _tag: "AuthenticationMD5Password";
readonly salt: Uint8Array;
}

AuthenticationOk

interface unstable
Since v4.0.0

Authentication succeeded.

Signature

interface AuthenticationOk {
readonly _tag: "AuthenticationOk";
}

AuthenticationSASL

interface unstable
Since v4.0.0

The server offers these SASL mechanisms.

Signature

interface AuthenticationSASL {
readonly _tag: "AuthenticationSASL";
readonly mechanisms: readonly Array<string>;
}

AuthenticationSASLContinue

interface unstable
Since v4.0.0

An opaque SASL challenge.

Signature

interface AuthenticationSASLContinue {
readonly _tag: "AuthenticationSASLContinue";
readonly data: Uint8Array;
}

AuthenticationSASLFinal

interface unstable
Since v4.0.0

The opaque final SASL payload, carrying the server signature.

Signature

interface AuthenticationSASLFinal {
readonly _tag: "AuthenticationSASLFinal";
readonly data: Uint8Array;
}

AuthenticationUnsupported

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

The identity a CancelRequest needs.

Signature

interface BackendKeyData {
readonly _tag: "BackendKeyData";
readonly pid: number;
readonly secret: number;
}

BackendMessage

type unstable
Since v4.0.0

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 | Unknown

Bind

interface unstable
Since v4.0.0

Binds parameter values to a prepared statement and creates a portal. Parameters and results use the binary format.

Signature

interface Bind {
readonly _tag: "Bind";
readonly parameters: readonly Array<Uint8Array<ArrayBufferLike> | null>;
readonly portal: string;
readonly statement: string;
}

BindComplete

interface unstable
Since v4.0.0

A Bind succeeded.

Signature

interface BindComplete {
readonly _tag: "BindComplete";
}

Close

interface unstable
Since v4.0.0

Drops a prepared statement or portal.

Signature

interface Close {
readonly _tag: "Close";
readonly name: string;
readonly target: DescribeTarget;
}

CloseComplete

interface unstable
Since v4.0.0

A Close succeeded.

Signature

interface CloseComplete {
readonly _tag: "CloseComplete";
}

CommandComplete

interface unstable
Since v4.0.0

A command finished, reporting its tag such as SELECT 3.

Signature

interface CommandComplete {
readonly _tag: "CommandComplete";
readonly commandTag: string;
}

CopyBothResponse

interface unstable
Since v4.0.0

The connection entered bidirectional COPY mode, as used by replication.

Signature

interface CopyBothResponse {
readonly _tag: "CopyBothResponse";
readonly columnFormats: readonly Array<number>;
readonly format: number;
}

CopyData

interface unstable
Since v4.0.0

A chunk of COPY data.

Signature

interface CopyData {
readonly _tag: "CopyData";
readonly data: Uint8Array;
}

CopyDone

interface unstable
Since v4.0.0

The COPY stream ended.

Signature

interface CopyDone {
readonly _tag: "CopyDone";
}

CopyInResponse

interface unstable
Since v4.0.0

The server is ready to receive COPY data.

Signature

interface CopyInResponse {
readonly _tag: "CopyInResponse";
readonly columnFormats: readonly Array<number>;
readonly format: number;
}

CopyOutResponse

interface unstable
Since v4.0.0

The server is about to send COPY data.

Signature

interface CopyOutResponse {
readonly _tag: "CopyOutResponse";
readonly columnFormats: readonly Array<number>;
readonly format: number;
}

DataRow

interface unstable
Since v4.0.0

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>;
}

Describe

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

Which kind of object a Describe or Close message names.

Signature

type DescribeTarget = "statement" | "portal"

EmptyQueryResponse

interface unstable
Since v4.0.0

The query string was empty.

Signature

interface EmptyQueryResponse {
readonly _tag: "EmptyQueryResponse";
}

ErrorFields

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

An error. code is the SQLSTATE.

Signature

interface ErrorResponse {
readonly _tag: "ErrorResponse";
readonly fields: ErrorFields;
}

Execute

interface unstable
Since v4.0.0

Runs a portal, optionally limiting the number of rows returned.

Signature

interface Execute {
readonly _tag: "Execute";
readonly maxRows: number;
readonly portal: string;
}

FieldDescription

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

Reads one DataRow field from the parser buffer.

Details

size is -1 for SQL NULL, and column is the field index. Only bytes from offset through offset + size belong to the field. A thrown error permanently fails the parser.

Signature

type FieldReader<A> = (bytes: Uint8Array, offset: number, size: number, column: number) => A

Flush

interface unstable
Since v4.0.0

Asks the backend to deliver buffered output without ending the transaction.

Signature

interface Flush {
readonly _tag: "Flush";
}

FrontendMessage

type unstable
Since v4.0.0

Any message the client sends after startup.

Signature

type FrontendMessage = Parse | Bind | Execute | Describe | Close | Sync | Flush | Terminate | PasswordMessage | SASLInitialResponse | SASLResponse

NegotiateProtocolVersion

interface unstable
Since v4.0.0

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>;
}

NoData

interface unstable
Since v4.0.0

The statement or portal returns no rows.

Signature

interface NoData {
readonly _tag: "NoData";
}

NoticeResponse

interface unstable
Since v4.0.0

A warning or notice. Same field set as ErrorResponse.

Signature

interface NoticeResponse {
readonly _tag: "NoticeResponse";
readonly fields: ErrorFields;
}

NotificationResponse

interface unstable
Since v4.0.0

A LISTEN/NOTIFY message.

Signature

interface NotificationResponse {
readonly _tag: "NotificationResponse";
readonly channel: string;
readonly payload: string;
readonly pid: number;
}

ParameterDescription

interface unstable
Since v4.0.0

The parameter OIDs of a described statement.

Signature

interface ParameterDescription {
readonly _tag: "ParameterDescription";
readonly parameterTypes: readonly Array<number>;
}

ParameterStatus

interface unstable
Since v4.0.0

Reports a run-time parameter value, at startup or whenever it changes.

Signature

interface ParameterStatus {
readonly _tag: "ParameterStatus";
readonly name: string;
readonly value: string;
}

Parse

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

A Parse succeeded.

Signature

interface ParseComplete {
readonly _tag: "ParseComplete";
}

Parser

interface unstable
Since v4.0.0

An incremental decoder for the post-startup backend message stream.

Signature

interface Parser<A = Uint8Array | null> {
readonly push: (chunk: Uint8Array) => readonly Array<BackendMessage<A>>;
readonly pushEach: (chunk: Uint8Array, onMessage: (message: BackendMessage<A>) => void) => void;
readField: FieldReader<A> | undefined;
}

PasswordMessage

interface unstable
Since v4.0.0

Answers a cleartext or MD5 password request.

Signature

interface PasswordMessage {
readonly _tag: "PasswordMessage";
readonly password: string;
}

PortalSuspended

interface unstable
Since v4.0.0

An Execute stopped at its row limit; the portal can be executed again.

Signature

interface PortalSuspended {
readonly _tag: "PortalSuspended";
}

ReadyForQuery

interface unstable
Since v4.0.0

The backend is ready for a new query cycle.

Signature

interface ReadyForQuery {
readonly _tag: "ReadyForQuery";
readonly status: TransactionStatus;
}

RowDescription

interface unstable
Since v4.0.0

Describes the columns a portal will return.

Signature

interface RowDescription {
readonly _tag: "RowDescription";
readonly fields: readonly Array<FieldDescription>;
}

SASLInitialResponse

interface unstable
Since v4.0.0

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 unstable
Since v4.0.0

Carries an opaque SASL continuation payload.

Signature

interface SASLResponse {
readonly _tag: "SASLResponse";
readonly data: Uint8Array;
}

StartupParameters

interface unstable
Since v4.0.0

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;
}

Sync

interface unstable
Since v4.0.0

Closes the current transaction block and requests a ReadyForQuery.

Signature

interface Sync {
readonly _tag: "Sync";
}

Terminate

interface unstable
Since v4.0.0

Ends the session.

Signature

interface Terminate {
readonly _tag: "Terminate";
}

TransactionStatus

type unstable
Since v4.0.0

Transaction status: idle, in a transaction block, or in a failed transaction block.

Signature

type TransactionStatus = "I" | "T" | "E"

Unknown

interface unstable
Since v4.0.0

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;
}

ValueSink

interface unstable
Since v4.0.0

A sink for writing parameter bytes into a Bind frame. The frame reserves and backfills each parameter length. PgTypes.writeParameter supports 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;
}