|
| 1 | +--- |
| 2 | +title: Postgres Wire Protocol |
| 3 | +description: Connect with psql, DBeaver, or any BI tool that speaks PostgreSQL. |
| 4 | +--- |
| 5 | + |
| 6 | +QueryMode includes a PostgreSQL wire protocol server. Any tool that connects to Postgres — `psql`, DBeaver, Metabase, Grafana, TablePlus, DataGrip — can query your data without code changes. |
| 7 | + |
| 8 | +## Quick start |
| 9 | + |
| 10 | +```bash |
| 11 | +# Start the pg-wire server (reads files from current directory) |
| 12 | +npx tsx src/pg-wire/server.ts |
| 13 | + |
| 14 | +# Connect with psql |
| 15 | +psql -h localhost -p 5433 -U querymode |
| 16 | +``` |
| 17 | + |
| 18 | +Then query as normal SQL: |
| 19 | + |
| 20 | +```sql |
| 21 | +SELECT * FROM './data/events.parquet' WHERE region = 'us' LIMIT 10; |
| 22 | +SELECT region, COUNT(*), AVG(amount) FROM './data/orders.lance' GROUP BY region; |
| 23 | +``` |
| 24 | + |
| 25 | +## Configuration |
| 26 | + |
| 27 | +| Environment variable | Default | Description | |
| 28 | +|---------------------|---------|-------------| |
| 29 | +| `PG_PORT` | `5433` | Listen port | |
| 30 | +| `PG_HOST` | `127.0.0.1` | Bind address | |
| 31 | + |
| 32 | +```bash |
| 33 | +PG_PORT=5432 PG_HOST=0.0.0.0 npx tsx src/pg-wire/server.ts |
| 34 | +``` |
| 35 | + |
| 36 | +## Supported SQL |
| 37 | + |
| 38 | +The pg-wire server uses QueryMode's SQL parser, so all [SQL syntax](/querymode/sql/) is supported: |
| 39 | + |
| 40 | +- `SELECT`, `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `OFFSET` |
| 41 | +- `JOIN` (inner, left, right, full, cross) |
| 42 | +- Window functions (`ROW_NUMBER`, `RANK`, `LAG`, `LEAD`, rolling aggregates) |
| 43 | +- CTEs (`WITH ... AS`) |
| 44 | +- Set operations (`UNION`, `INTERSECT`, `EXCEPT`) |
| 45 | +- Vector search (`WHERE embedding NEAR [...] TOPK 10`) |
| 46 | +- All 14 filter operators, `CASE`, `CAST`, arithmetic, `||` concatenation |
| 47 | +- `--` line comments and `/* */` block comments |
| 48 | + |
| 49 | +### Compatibility commands |
| 50 | + |
| 51 | +These are accepted and acknowledged for BI tool compatibility but have no effect: |
| 52 | + |
| 53 | +- `SET client_encoding TO 'UTF8'` |
| 54 | +- `RESET ALL` |
| 55 | +- `DISCARD ALL` |
| 56 | +- `SHOW <parameter>` (returns `"on"` for all parameters) |
| 57 | + |
| 58 | +## Programmatic use |
| 59 | + |
| 60 | +The `PgConnectionHandler` class can be embedded in any Node.js TCP server or WebSocket bridge: |
| 61 | + |
| 62 | +```typescript |
| 63 | +import { QueryMode } from "querymode/local" |
| 64 | +import { PgConnectionHandler } from "querymode" |
| 65 | +import * as net from "node:net" |
| 66 | + |
| 67 | +const qm = QueryMode.local() |
| 68 | + |
| 69 | +net.createServer((socket) => { |
| 70 | + const handler = new PgConnectionHandler({ |
| 71 | + executor: qm.getExecutor(), |
| 72 | + send: (data) => socket.write(data), |
| 73 | + }) |
| 74 | + |
| 75 | + socket.on("data", async (chunk) => { |
| 76 | + await handler.onData(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)) |
| 77 | + }) |
| 78 | +}).listen(5433) |
| 79 | +``` |
| 80 | + |
| 81 | +The handler manages the full connection lifecycle: |
| 82 | +1. **Startup** — SSL negotiation (rejected), authentication (always ok), server parameters |
| 83 | +2. **Query** — SQL parsing, compilation, execution via the QueryMode pipeline |
| 84 | +3. **Response** — `RowDescription` + `DataRow` messages with proper type OIDs |
| 85 | +4. **Error** — SQL errors return `ErrorResponse` and the connection stays open |
| 86 | + |
| 87 | +## Type mapping |
| 88 | + |
| 89 | +QueryMode types map to PostgreSQL type OIDs: |
| 90 | + |
| 91 | +| QueryMode type | Postgres type | OID | |
| 92 | +|---------------|--------------|-----| |
| 93 | +| `int8`, `int16` | `INT2` | 21 | |
| 94 | +| `int32` | `INT4` | 23 | |
| 95 | +| `int64` | `INT8` | 20 | |
| 96 | +| `float32` | `FLOAT4` | 700 | |
| 97 | +| `float64` | `FLOAT8` | 701 | |
| 98 | +| `utf8` | `TEXT` | 25 | |
| 99 | +| `bool` | `BOOL` | 16 | |
| 100 | +| `binary` | `BYTEA` | 17 | |
| 101 | + |
| 102 | +## Limitations |
| 103 | + |
| 104 | +- **Simple Query protocol only** — extended query protocol (prepared statements, `DESCRIBE`, `BIND`) is not supported. Most BI tools fall back to Simple Query automatically. |
| 105 | +- **No authentication** — all connections are accepted. Run behind a firewall or SSH tunnel for production use. |
| 106 | +- **No SSL/TLS** — SSL requests are rejected; clients retry in plaintext. Use an SSH tunnel or reverse proxy for encrypted connections. |
| 107 | +- **Local mode only** — the built-in server uses `LocalExecutor`. For edge mode, build a custom server that passes a `RemoteExecutor` to `PgConnectionHandler`. |
0 commit comments