|
| 1 | +# Claude Code Context for Duckgres |
| 2 | + |
| 3 | +This file provides context for Claude Code sessions working on this codebase. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Duckgres is a PostgreSQL wire protocol server backed by DuckDB. It allows any PostgreSQL client (psql, pgAdmin, lib/pq, psycopg2, JDBC, etc.) to connect and execute queries against DuckDB databases. |
| 8 | + |
| 9 | +## Architecture |
| 10 | + |
| 11 | +``` |
| 12 | +PostgreSQL Client → TLS → Duckgres Server → DuckDB (per-user database) |
| 13 | +``` |
| 14 | + |
| 15 | +### Key Components |
| 16 | + |
| 17 | +- **main.go**: Entry point, configuration loading (CLI flags, env vars, YAML) |
| 18 | +- **server/server.go**: Server struct, connection handling, graceful shutdown |
| 19 | +- **server/conn.go**: Client connection handling, query execution, COPY protocol |
| 20 | +- **server/protocol.go**: PostgreSQL wire protocol message encoding/decoding |
| 21 | +- **server/catalog.go**: pg_catalog compatibility (views, functions, query rewriting) |
| 22 | +- **server/types.go**: Type OID mapping between DuckDB and PostgreSQL |
| 23 | +- **server/ratelimit.go**: Rate limiting for brute-force protection |
| 24 | +- **server/tls.go**: Auto-generation of self-signed TLS certificates |
| 25 | + |
| 26 | +## PostgreSQL Wire Protocol |
| 27 | + |
| 28 | +The server implements the PostgreSQL v3 protocol: |
| 29 | + |
| 30 | +### Message Types (server/protocol.go) |
| 31 | +- **Frontend (client→server)**: Query, Parse, Bind, Describe, Execute, Sync, Close, CopyData, CopyDone |
| 32 | +- **Backend (server→client)**: AuthOK, RowDescription, DataRow, CommandComplete, ReadyForQuery, CopyInResponse, CopyOutResponse |
| 33 | + |
| 34 | +### Query Flow |
| 35 | +1. Client sends Query message ('Q') |
| 36 | +2. Server parses SQL, rewrites pg_catalog references |
| 37 | +3. Server executes via DuckDB's database/sql driver |
| 38 | +4. Server sends RowDescription + DataRow messages |
| 39 | +5. Server sends CommandComplete + ReadyForQuery |
| 40 | + |
| 41 | +### Extended Query Protocol |
| 42 | +Supports prepared statements (Parse/Bind/Execute) for parameterized queries and binary result formats. |
| 43 | + |
| 44 | +## pg_catalog Compatibility (server/catalog.go) |
| 45 | + |
| 46 | +psql and other clients expect PostgreSQL system catalogs. We provide compatibility by: |
| 47 | + |
| 48 | +1. **Creating views** in main schema that mirror pg_catalog tables: |
| 49 | + - `pg_database`, `pg_class_full`, `pg_collation`, `pg_policy`, `pg_roles` |
| 50 | + - `pg_statistic_ext`, `pg_publication`, `pg_publication_rel`, `pg_inherits`, etc. |
| 51 | + |
| 52 | +2. **Creating macros** for PostgreSQL functions: |
| 53 | + - `pg_get_userbyid`, `pg_table_is_visible`, `format_type`, `pg_get_expr` |
| 54 | + - `obj_description`, `col_description`, `pg_get_indexdef`, etc. |
| 55 | + |
| 56 | +3. **Query rewriting** to replace PostgreSQL-specific syntax: |
| 57 | + - `pg_catalog.pg_class` → `pg_class_full` |
| 58 | + - `OPERATOR(pg_catalog.~)` → `~` |
| 59 | + - `::pg_catalog.regtype` → `::VARCHAR` |
| 60 | + |
| 61 | +## COPY Protocol (server/conn.go) |
| 62 | + |
| 63 | +Supports bulk data transfer: |
| 64 | +- **COPY TO STDOUT**: Streams query results to client |
| 65 | +- **COPY FROM STDIN**: Receives data from client, inserts row by row |
| 66 | +- Supports CSV format with HEADER option |
| 67 | + |
| 68 | +## Configuration |
| 69 | + |
| 70 | +Three-tier configuration (highest to lowest priority): |
| 71 | +1. CLI flags (`--port`, `--config`, etc.) |
| 72 | +2. Environment variables (`DUCKGRES_PORT`, etc.) |
| 73 | +3. YAML config file |
| 74 | +4. Built-in defaults |
| 75 | + |
| 76 | +## Testing |
| 77 | + |
| 78 | +```bash |
| 79 | +# Build |
| 80 | +go build -o duckgres . |
| 81 | + |
| 82 | +# Run on non-standard port |
| 83 | +./duckgres --port 35437 |
| 84 | + |
| 85 | +# Connect with psql |
| 86 | +PGPASSWORD=postgres psql "host=127.0.0.1 port=35437 user=postgres sslmode=require" |
| 87 | + |
| 88 | +# Test commands |
| 89 | +\dt # List tables |
| 90 | +\d tablename # Describe table |
| 91 | +\l # List databases |
| 92 | +``` |
| 93 | + |
| 94 | +## Common Development Tasks |
| 95 | + |
| 96 | +### Adding a new pg_catalog view |
| 97 | +1. Add view creation SQL in `initPgCatalog()` in `catalog.go` |
| 98 | +2. Add regex pattern to rewrite `pg_catalog.viewname` to `viewname` |
| 99 | +3. Add the replacement in `rewritePgCatalogQuery()` |
| 100 | + |
| 101 | +### Adding a new PostgreSQL function |
| 102 | +1. Add `CREATE MACRO` in the `functions` slice in `initPgCatalog()` |
| 103 | +2. Add function name to `pgCatalogFunctions` slice for query rewriting |
| 104 | + |
| 105 | +### Adding protocol support |
| 106 | +1. Add message type constant in `protocol.go` |
| 107 | +2. Add write function (e.g., `writeCopyData()`) |
| 108 | +3. Handle in message loop in `conn.go` |
| 109 | + |
| 110 | +## Dependencies |
| 111 | + |
| 112 | +- `github.com/duckdb/duckdb-go/v2` - DuckDB Go driver |
| 113 | +- `gopkg.in/yaml.v3` - YAML config parsing |
| 114 | + |
| 115 | +## Known Limitations |
| 116 | + |
| 117 | +- Single process (all users share one process) |
| 118 | +- No replication |
| 119 | +- Some pg_catalog tables are stubs (return empty) |
| 120 | +- Type OID mapping is incomplete (some types show as "unknown") |
| 121 | + |
| 122 | +## TODO Reference |
| 123 | + |
| 124 | +See `TODO.md` for the full feature roadmap and known issues. |
0 commit comments