Skip to content

Commit 082aba0

Browse files
bill-phclaude
andauthored
docs: canonical PostgreSQL compatibility matrix (#762)
* docs: add canonical PostgreSQL compatibility matrix Add docs/postgres-compatibility.md: a single, feature-by-feature record of which PostgreSQL functionality Duckgres supports and which tests prove it, with specific test citations (file.go::TestName) per row. Consolidates coverage info previously smeared across README.md, tests/integration/README.md, and TODO.md. Each row carries a status (Covered / Partial / Implemented-untested / Unsupported / Out-of-scope) and links to the differential, unit, or client-compat test that exercises it. Surfaces the real gaps, notably: cursors (DECLARE/FETCH/MOVE) are implemented in server/conn_cursor.go but have no happy-path test, and the differential RETURNING / COPY TO STDOUT skips are stale. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: consolidate README compatibility tables into the canonical matrix Shrink README's "SQL Client Compatibility" section to a short summary plus a link to docs/postgres-compatibility.md, and relocate the detailed pg_catalog / information_schema / functions / startup-parameter reference tables into that doc as Appendix A so there is one source of truth. Fix verified-stale entries during the move: - current_schema(), pg_settings, pg_proc were labelled "Missing" though they work via DuckDB's native pg_catalog (no Duckgres wrapper) -> "Native (DuckDB)" - pg_roles is a minimal one-row view, not an empty stub - clarify pg_stat_activity (static view empty; live data injected at query time) The advertised server_version (15.0) is left as-is: it matches the code (server/catalog.go, server/conn.go) and is an intentional emulation choice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2ddb549 commit 082aba0

2 files changed

Lines changed: 401 additions & 95 deletions

File tree

README.md

Lines changed: 3 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -761,101 +761,9 @@ Since DuckDB's isolation is strictly stronger than PostgreSQL's default, applica
761761

762762
## SQL Client Compatibility
763763

764-
Duckgres implements a subset of PostgreSQL's system catalog to satisfy introspection queries from common SQL clients, ORMs, and BI tools. The tables below document current coverage.
765-
766-
### pg_catalog Views
767-
768-
| View | Status | Notes |
769-
|------|--------|-------|
770-
| `pg_class` | Implemented | `pg_class_full` wrapper adding `relforcerowsecurity`; DuckLake variant sources from `duckdb_tables()`/`duckdb_views()` |
771-
| `pg_namespace` | Implemented | Maps `main` → `public`; DuckLake variant derives from `duckdb_tables()`/`duckdb_views()` |
772-
| `pg_attribute` | Implemented | Maps DuckDB internal type OIDs to PG OIDs via `duckdb_columns()` JOIN; fixes `atttypmod` for NUMERIC |
773-
| `pg_type` | Implemented | Fixes NULLs + adds synthetic entries for missing OIDs (json, jsonb, bpchar, text, record, array types) |
774-
| `pg_database` | Implemented | Hardcoded: postgres, template0, template1, testdb |
775-
| `pg_stat_user_tables` | Implemented | Uses `reltuples` from pg_class; zeros for scan/tuple stats |
776-
| `pg_roles` | Stub (empty) | Single hardcoded `duckdb` superuser |
777-
| `pg_constraint` | Stub (empty) | |
778-
| `pg_enum` | Stub (empty) | |
779-
| `pg_collation` | Stub (empty) | |
780-
| `pg_policy` | Stub (empty) | |
781-
| `pg_inherits` | Stub (empty) | |
782-
| `pg_statistic_ext` | Stub (empty) | |
783-
| `pg_publication` | Stub (empty) | |
784-
| `pg_publication_rel` | Stub (empty) | |
785-
| `pg_publication_tables` | Stub (empty) | |
786-
| `pg_rules` | Stub (empty) | |
787-
| `pg_matviews` | Stub (empty) | |
788-
| `pg_partitioned_table` | Stub (empty) | |
789-
| `pg_stat_activity` | Stub (empty) | Intercepted at query time for live data |
790-
| `pg_statio_user_tables` | Stub (empty) | |
791-
| `pg_stat_statements` | Stub (empty) | |
792-
| `pg_indexes` | Stub (empty) | |
793-
| `pg_settings` | Missing | `current_setting()` macro handles `server_version` and `server_encoding` only |
794-
| `pg_proc` | Missing | DuckDB has native `pg_catalog.pg_proc` but no wrapper |
795-
| `pg_description` | Missing | Handled via `obj_description()`/`col_description()` macros returning NULL |
796-
| `pg_depend` | Missing | |
797-
| `pg_am` | Missing | |
798-
| `pg_attrdef` | Missing | |
799-
| `pg_tablespace` | Missing | |
800-
801-
### information_schema Views
802-
803-
| View | Status | Notes |
804-
|------|--------|-------|
805-
| `tables` | Implemented | Filters internal views, normalizes `main` → `public` |
806-
| `columns` | Implemented | DuckDB → PG type name normalization, optional metadata overlay |
807-
| `schemata` | Implemented | Adds synthetic entries for `pg_catalog`, `information_schema`, `pg_toast` |
808-
| `views` | Implemented | Filters internal views |
809-
| `key_column_usage` | Missing | Used by ORMs for relationship discovery |
810-
| `table_constraints` | Missing | Used by ORMs for relationship discovery |
811-
| `referential_constraints` | Missing | Used by ORMs for FK introspection |
812-
813-
### Functions & Macros
814-
815-
| Function | Status | Notes |
816-
|----------|--------|-------|
817-
| `format_type(oid, int)` | Implemented | Comprehensive OID → name mapping |
818-
| `pg_get_expr(text, oid)` | Implemented | Returns NULL |
819-
| `pg_get_indexdef(oid)` | Implemented | Returns empty string |
820-
| `pg_get_constraintdef(oid)` | Implemented | Returns empty string |
821-
| `pg_get_serial_sequence(text, text)` | Implemented | Returns NULL |
822-
| `pg_table_is_visible(oid)` | Implemented | Always true |
823-
| `pg_get_userbyid(oid)` | Implemented | Maps OID 10 → `postgres`, 6171 → `pg_database_owner` |
824-
| `obj_description(oid, text)` | Implemented | Returns NULL |
825-
| `col_description(oid, int)` | Implemented | Returns NULL |
826-
| `shobj_description(oid, text)` | Implemented | Returns NULL |
827-
| `has_table_privilege(text, text)` | Implemented | Always true |
828-
| `has_schema_privilege(text, text)` | Implemented | Always true |
829-
| `pg_encoding_to_char(int)` | Implemented | Always `UTF8` |
830-
| `version()` | Implemented | Returns PG 15.0 compatible string |
831-
| `current_setting(text)` | Implemented | Handles `server_version` and `server_encoding` |
832-
| `pg_is_in_recovery()` | Implemented | Always false |
833-
| `pg_backend_pid()` | Implemented | Returns 0 |
834-
| `pg_size_pretty(bigint)` | Implemented | Full human-readable formatting |
835-
| `pg_total_relation_size(oid)` | Implemented | Returns 0 |
836-
| `pg_relation_size(oid)` | Implemented | Returns 0 |
837-
| `pg_table_size(oid)` | Implemented | Returns 0 |
838-
| `pg_indexes_size(oid)` | Implemented | Returns 0 |
839-
| `pg_database_size(text)` | Implemented | Returns 0 |
840-
| `quote_ident(text)` | Implemented | |
841-
| `quote_literal(text)` | Implemented | |
842-
| `quote_nullable(text)` | Implemented | |
843-
| `txid_current()` | Implemented | Epoch-based pseudo ID |
844-
| `current_schema()` | Missing | |
845-
| `current_schemas(bool)` | Missing | |
846-
847-
### Startup Parameters
848-
849-
| Parameter | Value |
850-
|-----------|-------|
851-
| `server_version` | `15.0 (Duckgres)` |
852-
| `server_encoding` | `UTF8` |
853-
| `client_encoding` | `UTF8` |
854-
| `DateStyle` | `ISO, MDY` |
855-
| `TimeZone` | `UTC` |
856-
| `integer_datetimes` | `on` |
857-
| `standard_conforming_strings` | `on` |
858-
| `IntervalStyle` | Missing |
764+
Duckgres implements a subset of PostgreSQL's system catalog to satisfy introspection queries from common SQL clients, ORMs, and BI tools — enough for psql, pgAdmin, DBeaver, Metabase, Grafana, Superset, Tableau, Fivetran, Airbyte, dbt, and the standard drivers (psycopg, pgx, JDBC, node-postgres, tokio-postgres, SQLAlchemy) to connect and introspect.
765+
766+
The full, authoritative breakdown — every PostgreSQL feature with its support status and the specific test that proves it, plus the per-object `pg_catalog`/`information_schema`/function/startup-parameter reference — lives in **[docs/postgres-compatibility.md](docs/postgres-compatibility.md)**. That document is the single source of truth; update it in the same PR as any PostgreSQL-visible behavior change.
859767

860768
## Dependencies
861769

0 commit comments

Comments
 (0)