pg_stream
A low-level, zero-overhead Rust implementation of the Postgres wire protocol.
Overview
pg_stream provides direct access to the Postgres frontend/backend protocol, giving you full control over connection management, query execution, and data transfer. Unlike higher-level database libraries, this crate focuses on protocol implementation without abstraction overhead.
Features
- Zero-copy protocol handling - Direct buffer manipulation for maximum performance
- TLS support - Built-in SSL/TLS negotiation with custom upgrade functions
- Extended query protocol - Full support for prepared statements, portals, and parameter binding
- Function calls - Direct invocation of Postgres functions via protocol messages
- Extension trait API - Write messages to any buffer implementing
BufMut - Format optimization - Automatic optimization of format codes in bind and function call messages
Quick Start
use ;
use PgProtocol;
use backend;
async
Authentication
Supported authentication modes:
AuthenticationMode::Trust- No password requiredAuthenticationMode::Password(String)- Cleartext or SCRAM-SHA-256 password authentication
Extended Query Protocol
The crate provides full support for the extended query protocol with prepared statements:
use PgProtocol;
use oid;
// Parse a prepared statement
conn.parse
.query
.param_types
.finish;
conn.flush.await?;
// Bind parameters and execute
conn.bind
.finish
.execute
.sync;
conn.flush.await?;
Function Calls
Call Postgres functions directly via the protocol:
use PgProtocol;
use FormatCode;
// Call sqrt function (OID 1344)
conn.fn_call
.result_format
.finish;
conn.flush.await?;
Note: Function OIDs are not guaranteed to be stable across Postgres versions or installations. Look them up dynamically via system catalogs for production use.
TLS Support
Connect with TLS using a custom upgrade function:
let stream = connect.await.unwrap;
stream.set_nodelay.unwrap;
let = new
.connect_with_tls
.await
.unwrap;
Protocol Messages
The PgProtocol trait provides methods for all major frontend protocol messages:
- Simple Query -
query() - Parse -
parse()builder for prepared statements - Bind -
bind()builder to bind parameters - Describe -
describe_statement(),describe_portal() - Execute -
execute()to run a portal - Close -
close_statement(),close_portal() - Flush -
flush_msg()to send buffered messages - Sync -
sync()to end an extended query sequence - Function Call -
fn_call()builder to invoke functions
Performance
This crate is designed for scenarios where you need maximum control and minimum overhead:
- Direct buffer manipulation with
bytes::BytesMut - No allocations in the hot path for protocol framing
- Zero-copy reads where possible
- Efficient format code optimization
- Minimum dependencies
Safety and Limitations
- No SQL injection protection - You are responsible for sanitizing inputs
- No connection pooling - Single connection per
PgConnection - Manual resource management - You must close statements and portals
- Incomplete auth support - Only Trust, SCRAM-SHA-256, and cleartext password