async_postgres/pg_client/direct

Zero-allocation queryDirect / execDirect compile-time macros that encode parameters directly into the connection send buffer.

Procs

proc execDirectImpl(conn: PgConnection; sql: string; cacheHit: bool;
                    cacheMiss: bool; stmtName: string;
                    timeout: Duration = ZeroDuration): Future[CommandResult] {.
    ...stackTrace: false, raises: [Exception, ValueError, CatchableError],
    tags: [RootEffect, TimeEffect], forbids: [].}
Trace + timeout wrapper for the execDirect macro. Parameter encoding has already completed synchronously in the macro expansion before this proc is invoked.
proc execDirectRunImpl(conn: PgConnection; sql: string; cacheHit: bool;
                       cacheMiss: bool; stmtName: string; timeout: Duration): Future[
    string] {....stackTrace: false, raises: [Exception, ValueError, SslError,
    ProtocolError, PgQueryError, KeyError, AsyncTimeoutError, CatchableError,
    PgConnectionError], tags: [RootEffect, TimeEffect], forbids: [].}
Inner send + receive loop for execDirect. Returns the command tag and handles error reporting / cache bookkeeping. Split out so the outer Impl can apply .wait(timeout) without an extra closure alloc.
proc queryDirectImpl(conn: PgConnection; sql: string; resultFormats: seq[int16];
                     colFmts: seq[int16]; colOids: seq[int32]; cacheHit: bool;
                     cacheMiss: bool; stmtName: string;
                     cachedFields: seq[FieldDescription];
                     timeout: Duration = ZeroDuration): Future[QueryResult] {.
    ...stackTrace: false, raises: [Exception, ValueError, CatchableError],
    tags: [RootEffect, TimeEffect], forbids: [].}
Trace + timeout wrapper for the queryDirect macro. The synchronous parameter-encoding step already filled conn.sendBuf before this proc was called, so tracing fires around the network round-trip only — which matches the behavior tracers see for query / exec.
proc queryDirectRunImpl(conn: PgConnection; sql: string;
                        resultFormats: seq[int16]; colFmts: seq[int16];
                        colOids: seq[int32]; cacheHit: bool; cacheMiss: bool;
                        stmtName: string; cachedFields: seq[FieldDescription];
                        timeout: Duration): Future[QueryResult] {.
    ...stackTrace: false, raises: [Exception, ValueError, SslError, ProtocolError,
                                PgQueryError, KeyError, AsyncTimeoutError,
                                CatchableError, PgConnectionError],
    tags: [RootEffect, TimeEffect], forbids: [].}
Inner send + receive loop for queryDirect. Pulled out so the outer Impl can wrap the returned Future with .wait(timeout) without paying for a closure allocation (mirrors the queryImpl / query* split in query.nim).

Macros

macro execDirect(conn: PgConnection; sql: string; args: varargs[untyped]): untyped

Zero-allocation exec: encodes parameters directly into the send buffer at compile time, avoiding seq[PgParam] and intermediate seq[byte] allocs.

Usage: discard await conn.execDirect("UPDATE ... WHERE id = $1", myId) discard await conn.execDirect( "UPDATE ... WHERE id = $1", myId, timeout = 1.seconds)

Tracing fires the onQueryStart / onQueryEnd hooks with only sql populated — params is left empty to preserve the zero-alloc guarantee.

macro queryDirect(conn: PgConnection; sql: string; args: varargs[untyped]): untyped

Zero-allocation query: encodes parameters directly into the send buffer at compile time, avoiding seq[PgParam] and intermediate seq[byte] allocs.

Usage: let qr = await conn.queryDirect("SELECT ... WHERE id = $1", myId) let qr = await conn.queryDirect( "SELECT ... WHERE id = $1", myId, timeout = 1.seconds)

Tracing fires the onQueryStart / onQueryEnd hooks with only sql populated — params is left empty to preserve the zero-alloc guarantee.