kdb-gateway v0.0.13 vs `pg_dump` v17 — Coverage Diff
Status: draft (2026-05-11) · Ticket: infra/data/kdb#339 · Spec: pg-dump-v17.kmd · Captures: captures/ · kdb surface: infra/data/kdb/crates/kdb-pgwire/src/handler/pg_catalog_tables.rs
This is the gap analysis between the queries pg_dump --version 17 issues (captured in captures/pg-dump-v17-queries-*.sql) and the pg_catalog rows + functions that kdb-pgwire v0.0.13 currently exposes. Each row is mapped to a follow-up ticket in infra/data/kdb#341 (the implementation umbrella).
Severity legend:
- R-CRITICAL — pg_dump aborts the dump if missing.
- R-IMPORTANT — pg_dump skips the affected object class (e.g. no
sequences in the dump) but the overall dump succeeds.
- R-COSMETIC — pg_dump produces a slightly less-rich dump (missing
COMMENT ON, missing privilege grants, etc.) but the schema is recoverable. - R-OK — kdb already covers; included for inventory completeness.
1. Relations
| Relation | kdb v0.0.13 | pg_dump v17 needs | Severity | Follow-up |
|---|---|---|---|---|
pg_roles |
✅ present | oid, rolname |
R-OK | — |
pg_extension |
✅ present | full row | R-OK | — |
pg_depend |
✅ present | full row | R-OK | — |
pg_namespace |
✅ present | nspacl + acldefault |
R-OK | — |
pg_class |
⚠ partial | relispartition, relrowsecurity, relforcerowsecurity, relminmxid, relfrozenxid |
R-CRITICAL | #341-class-rows |
pg_proc |
✅ present | full row, filter prokind <> 'a' |
R-OK | — |
pg_type |
✅ present | typacl, typtype, typrelkind |
R-OK | — |
pg_language |
✅ present | lanispl filter |
R-OK | — |
pg_attribute |
⚠ partial | attcompression, attmissingval, attstattarget, attstorage (must be "char"), attgenerated, attidentity |
R-CRITICAL | #341-attribute-v17 |
pg_constraint |
✅ present | confupdtype, confdeltype, confmatchtype, convalidated |
R-IMPORTANT | #341-constraint-v17 |
pg_index |
✅ present | indcollation, indclass, indoption, indpred, indexprs |
R-IMPORTANT | #341-index-v17 |
pg_inherits |
✅ present | inhseqno |
R-OK | — |
pg_description |
✅ present | full row | R-OK | — |
pg_publication |
✅ present | full row, empty OK | R-OK | — |
pg_settings |
✅ present | restrict_nonsystem_relation_kind row |
R-OK | — |
pg_foreign_table |
✅ present | empty OK | R-OK | — |
pg_cast |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-cast |
pg_collation |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-collation |
pg_conversion |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-conversion |
pg_default_acl |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-default-acl |
pg_event_trigger |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-event-trigger |
pg_init_privs |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-init-privs |
pg_opclass |
❌ missing | opcname, opcfamily, opcintype, opcdefault |
R-IMPORTANT | #341-pg-opclass |
pg_operator |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-operator |
pg_opfamily |
❌ missing | opfname, opfmethod, opfnamespace, opfowner |
R-IMPORTANT | #341-pg-opfamily |
pg_publication_namespace |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-publication-namespace |
pg_range |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-range |
pg_rewrite |
❌ missing | ev_class, rulename, ev_type, ev_qual, ev_action |
R-CRITICAL (views) | #341-pg-rewrite |
pg_seclabels |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-seclabels |
pg_sequence |
❌ missing | seqstart, seqincrement, seqmax, seqmin, seqcache, seqcycle |
R-CRITICAL (sequences) | #341-pg-sequence |
pg_statistic_ext |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-statistic-ext |
pg_tablespace |
❌ missing | full row, empty OK | R-IMPORTANT | #341-pg-tablespace |
pg_transform |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-transform |
pg_ts_* |
❌ missing | full row, empty OK | R-COSMETIC | #341-pg-ts |
2. Functions
| Function | kdb v0.0.13 | Severity | Follow-up |
|---|---|---|---|
pg_is_in_recovery() |
✅ present | R-OK | — |
pg_get_viewdef(oid) |
⚠ stub returns "" | R-CRITICAL (views) | #341e |
pg_get_indexdef(oid) |
⚠ stub returns "" | R-IMPORTANT | #341-fn-pggetindexdef |
pg_get_constraintdef(oid) |
⚠ stub returns "" | R-CRITICAL (constraints) | #341f |
pg_get_triggerdef(oid) |
⚠ stub returns "" | R-COSMETIC | #341-fn-pggettriggerdef |
pg_get_expr(node, relid) |
⚠ stub returns "" | R-IMPORTANT (defaults / partial idx) | #341-fn-pggetexpr |
pg_get_serial_sequence(table, col) |
⚠ stub returns "" | R-CRITICAL (SERIAL / IDENTITY) | #341g |
pg_options_to_table(text[]) |
❌ missing | R-COSMETIC (FDW) | #341-fn-pgoptionsto_table |
acldefault(char, oid) |
❌ missing | R-IMPORTANT (every ACL query embeds it) | #341-fn-acldefault |
array_remove(any[], any) |
✅ present (fn_array_remove em kdb-planner/src/functions.rs:3516) |
R-OK | — (#341h closed 2026-05-11) |
Note:
array_removeis reachable by the samepg_classmega-query that drives the object loop; a stub that returns the input unchanged is enough for pg_dump to proceed (the rewrite valuescheck_option=local|cascadedonly matter for views withWITH CHECK OPTIONand are nullable).
3. Session GUCs
| GUC | kdb behavior | Severity | Follow-up |
|---|---|---|---|
search_path |
✅ accepts SET | R-OK | — |
DATESTYLE = ISO |
✅ accepts SET | R-OK | — |
INTERVALSTYLE = POSTGRES |
✅ accepts SET | R-OK | — |
extra_float_digits = 3 |
✅ accepts SET | R-OK | — |
synchronize_seqscans = off |
✅ accepts SET | R-OK | — |
statement_timeout = 0 |
✅ accepts SET | R-OK | — |
lock_timeout = 0 |
✅ accepts SET | R-OK | — |
idle_in_transaction_session_timeout = 0 |
✅ | R-OK | — |
transaction_timeout = 0 |
⚠ unknown | R-COSMETIC | #341-guc-transaction_timeout |
row_security = off |
✅ accepts SET | R-OK | — |
restrict_nonsystem_relation_kind |
❌ absent | R-COSMETIC (PG 17 hardening flag) | #341-guc-restrict-nsk |
4. Wire-protocol features
| Feature | kdb v0.0.13 | Severity | Follow-up |
|---|---|---|---|
BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ ONLY |
✅ present | R-OK | — |
LOCK TABLE … IN ACCESS SHARE MODE |
⚠ partial (parsed, may be no-op) | R-IMPORTANT | #341-lock-table-as-noop |
COPY <table> TO STDOUT |
✅ shipped in v0.0.14 (#340) | R-OK | — |
CopyOutResponse + CommandComplete("COPY n") framing |
✅ | R-OK | — |
5. Summary
| Bucket | Count |
|---|---|
| R-CRITICAL gaps | 6 (was 7; -1 = array_remove already present) |
| R-IMPORTANT gaps | 13 |
| R-COSMETIC gaps | 12 |
| R-OK | 24 (was 23; +1 = array_remove) |
Closed since the diff was first written (2026-05-11):
- #341a ✅ —
pg_classPG 17 columns landed (commit6056a33bbe). - #341b ✅ —
pg_attributePG 17 row shape landed (commit4f1aa7c334). - #341h ✅ —
array_removediscovered to already be present(
kdb-planner/src/functions.rs:3516); diff entry corrected.
Remaining R-CRITICAL: pgrewrite, pgsequence, pggetviewdef, pggetconstraintdef, pggetserialsequence (5). The pgget_*def functions exist as stubs that return "" — they need real implementations, not new registrations.
To make pg_dump --schema-only --no-owner --no-acl against kdb-gateway succeed end-to-end on the audit schema, the 7 critical items above MUST land in infra/data/kdb#341:
pg_classextra columns (relispartition, RLS bools,relminmxid,relfrozenxid).pg_attributev17 row shape (attcompression,attmissingval,attstattarget,attstorageas"char",attgenerated,attidentity).pg_rewritetable (drives view body materialization).pg_sequencetable (sequence parameters).pg_get_viewdef(oid)function.pg_get_constraintdef(oid)function.pg_get_serial_sequence(table, col)function.array_remove(any[], any)function (stub returning inputunchanged is enough).
R-IMPORTANT items unblock specific object classes (operator classes, collations, tablespaces, …) and should be tackled in priority order of how often each object class appears in real-world Postgres schemas — but none of them block the smoke-test schema in the audit.
R-COSMETIC items only matter for high-fidelity dumps and can be implemented opportunistically.