Skip to main content

PostgreSQL Wire Protocol

The SochDB v2 server (sochdb-grpc-server) speaks a subset of the PostgreSQL wire protocol v3 on a dedicated port, so standard PostgreSQL clients — psql, ORMs, and language drivers — can connect and run SQL without any SochDB-specific client library. It is implemented in sochdb-grpc/src/pg_wire.rs.

This is a convenience surface aimed at ad-hoc querying and tooling that already speaks Postgres. The gRPC port remains the primary, authenticated network interface — see the gRPC Server page.

Quick start

The PG wire port is enabled by default on 5433. Connect with psql:

# Start the server (PG wire on 5433 by default, real SQL persisted under ./pgdata)
sochdb-grpc-server --pg-data-dir ./pgdata

# Connect with the standard PostgreSQL client
psql -h 127.0.0.1 -p 5433 -d sochdb

The startup banner prints the connection string in URL form: postgresql://<host>:5433/sochdb. No username or password is required (see Limitations below).

CLI flags

The PG wire surface is controlled by two flags on the server binary. See the gRPC Server page for the complete flag reference.

FlagDefaultEnv varPurpose
--pg-port5433PostgreSQL wire-protocol port. Set to 0 to disable.
--pg-data-dirnoneSOCHDB_PG_DATA_DIRPersistent directory that enables real SQL execution. Without it, the port runs an echo placeholder.
# Disable the PG wire port entirely
sochdb-grpc-server --pg-port 0

# Use a custom port and persistent data directory
sochdb-grpc-server --pg-port 5500 --pg-data-dir /var/lib/sochdb/sql

Real SQL vs. echo placeholder

The server selects one of two executors at startup based on whether --pg-data-dir is set:

  • With --pg-data-dir — a DatabasePgExecutor runs real SQL against a persistent sochdb_storage::Database opened at that directory. It supports SELECT, INSERT, UPDATE, DELETE, and DDL — including JOINs — through the SQL bridge (SqlBridge<DatabaseSqlConnection>). If the database cannot be opened, the server fails fast rather than silently degrading, so you never get fabricated results that look real.
  • Without --pg-data-dir — an EchoPgExecutor placeholder simply echoes the query back. This is useful for verifying connectivity and the protocol handshake, but it does not execute SQL.
Use --pg-data-dir for actual queries

If you want to run SQL, always pass --pg-data-dir. The echo executor is a connectivity placeholder only — it will not read or write any data.

-- With --pg-data-dir, this runs as real SQL over the persistent database
CREATE TABLE users (id BIGINT, name TEXT, active BOOL);
INSERT INTO users VALUES (1, 'ada', true), (2, 'grace', false);

SELECT u.id, u.name
FROM users u
WHERE u.active = true;

Protocol scope

The PG wire implementation targets a deliberately small slice of the protocol (documented as "v1" scope in the source):

  • Simple Query Protocol only. The Extended Query protocol — parameterized prepared statements (Parse/Bind/Execute) — is not supported. Send SQL as plain query strings.
  • Protocol version 3 (196608). SSL negotiation and cancel-request packets are recognized at the protocol level, but TLS itself is not offered.
  • Trust authentication. No password is requested or checked.
Not a secured surface — bind to loopback only

The PG wire port has no authentication layer (unlike the gRPC auth interceptor):

  • Simple Query Protocol only — no extended/prepared statements.
  • No SSL/TLS — all traffic is cleartext.
  • Trust auth — no password is required; anyone who can reach the port can read and, with --pg-data-dir, modify all data.

When --pg-data-dir is set and --host is not a loopback address (127.0.0.1, ::1, or localhost), the server logs a loud warning at startup because a writable SQL database would be exposed unauthenticated on the network.

Keep the PG wire port bound to loopback (127.0.0.1), or place it behind an authenticating proxy. Do not expose it directly on a public interface.

Because the echo placeholder mode (no --pg-data-dir) cannot read or write data, only the real-SQL mode carries the exposure risk above — but the absence of auth applies to both modes regardless.

Type-to-OID mapping

When a result set is returned, SochDB maps each column's type name to a PostgreSQL type OID so that client drivers decode values correctly (type_to_oid in pg_wire.rs). The mapping is case-insensitive on the SochDB type name:

SochDB / SQL typePostgreSQL typeOID
INT, INTEGER, BIGINT, INT8, SERIAL, BIGSERIALINT8 (bigint)20
FLOAT, DOUBLE, FLOAT8, REAL, FLOAT4, NUMERIC, DECIMALFLOAT8 (double precision)701
TEXT, VARCHAR, CHAR, STRING, CHARACTER VARYINGTEXT25
BOOL, BOOLEANBOOL16
BYTEA, BINARY, BLOBBYTEA17
JSON, JSONB, MAP, OBJECT, ARRAYJSONB3802
anything elseTEXT (fallback)25
Integers map to INT8

All integer widths (including 32-bit INT/INTEGER) are reported as INT8 (bigint, OID 20). Floating-point and NUMERIC/DECIMAL types are reported as FLOAT8 (OID 701). Composite and document types collapse to JSONB (OID 3802). Unrecognized type names fall back to TEXT (OID 25).

Connecting with a driver

Any client that speaks the simple query protocol works. Use a connection string of the form postgresql://127.0.0.1:5433/sochdb with no credentials.

psql -h 127.0.0.1 -p 5433 -d sochdb

Limitations

  • No prepared statements / extended query protocol — send literal SQL strings.
  • No TLS on this port; traffic is cleartext.
  • No authentication — protect the port with network scoping (loopback) or a proxy.
  • Without --pg-data-dir, queries are echoed, not executed.
  • All PG connections share a single SQL bridge behind a mutex, so concurrent sessions are serialized at the bridge.
  • gRPC Server — the primary authenticated interface, full CLI flag reference, and port summary.
  • IPC Server — the local Unix-socket transport.
  • Bulk Operations Tool — offline index builds and conversions.