Repository navigation
fix: batch per-row inspector lookups into the schema queries (#644, #654) - #656
Conversation
) The inspector issued one query per privilege row to resolve the grantee name, one per constraint column for its position in the key, one per owned sequence for the identity flag, and one per view for its column list. Over a high-latency connection that made dump and plan take minutes: the 200-table reproduction in #644 needed 4,028 queries per inspection, and plan inspects twice. Each value now comes back from the batched query it belongs to: - GetPrivilegesForSchema / GetColumnPrivilegesForSchema LEFT JOIN pg_roles on the aclexplode grantee and return grantee_name ('PUBLIC' for oid 0, empty when the role is gone, which keeps the skip behavior). - GetConstraintsForSchema returns array_position(conkey, attnum) as constraint_position for PK/UNIQUE/FK constraints. - GetSequencesForSchema returns owned_by_identity from the owning column's attidentity. - GetViewsForSchema returns column_names aggregated from pg_attribute. The reproduction drops from 4,028 to 30 queries; the employee fixture from 164 to 30. Dump output is unchanged on both. This also fixes a correctness bug: the old position lookup keyed on (schema, constraint name, column) without the table, so two tables with a same-named foreign key on the same columns could get each other's column order. New dump fixture issue_644_fk_column_order covers it. GetIndexesForSchema coalesces parent_index / parent_index_schema so that regenerating with sqlc v1.30.0 yields the nullable type the inspector already uses; the generated code had drifted from the generator. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The queries and inspector consumers are consistent, the ordering fix has regression coverage, and no blocking issues remain.
0 open findings
What changed in this PR
Reduces database round trips during dump and plan by batching inspector metadata lookups, addressing slow remote introspection.
Changes:
- Fetches privilege names, constraint positions, sequence identity flags, and view columns in existing queries.
- Updates generated bindings and removes per-row inspector queries.
- Fixes same-named foreign key column ordering with regression coverage.
| File | Description |
|---|---|
testdata/dump/issue_644_fk_column_order/raw.sql |
Reproduces conflicting foreign key column orders. |
testdata/dump/issue_644_fk_column_order/pgschema.sql |
Records expected pgschema output. |
testdata/dump/issue_644_fk_column_order/pgdump.sql |
Provides reference PostgreSQL output. |
testdata/dump/issue_644_fk_column_order/manifest.json |
Documents the regression fixture. |
ir/queries/queries.sql.go |
Updates generated query bindings. |
ir/queries/queries.sql |
Batches metadata lookups. |
ir/inspector.go |
Consumes batched metadata. |
cmd/dump/dump_integration_test.go |
Registers the ordering regression test. |
Files not reviewed (1)
- ir/queries/queries.sql.go: Generated file
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
[High impact] The PR appears safe to merge; no actionable issues were found. SummaryThis PR moves repeated inspector lookups into the existing schema queries.
No actionable issues found. Tests were not run during this review. Reviews (1) · Last reviewed commit: "fix: batch per-row inspector lookups int..." · Reviewed by Greptile |
Summary
dumpandplanwere slow over high-latency connections because the inspector did one round trip per privilege row (role name), per constraint column (position in the key), per owned sequence (identity flag) and per view (column list). Each value now comes back from the batched query it belongs to, so introspection is a fixed ~30 queries regardless of schema size.dump, one inspection)employeefixture with grants to two rolesCounts from the
--debugquery tree (#655).planinspects twice, so the user-facing saving doubles. Dump output is byte-identical before and after on both databases.Query changes (
ir/queries/queries.sql)GetPrivilegesForSchema,GetColumnPrivilegesForSchema: theaclexploderows move into a CTE andLEFT JOIN pg_roleson the grantee;grantee_nameisPUBLICfor oid 0 and empty when the role no longer exists, which keeps today's skip behavior.GetConstraintsForSchema:constraint_position = array_position(conkey, attnum)for PK / UNIQUE / FK, 0 otherwise. Same valueinformation_schema.key_column_usage.ordinal_positiongave.GetSequencesForSchema:owned_by_identityfrom the owning column'sattidentity.GetViewsForSchema:column_namesaggregated frompg_attributeinattnumorder.GetIndexesForSchema:COALESCEonparent_index/parent_index_schema. The checked-in generated code had drifted from what sqlc v1.30.0 produces for these two columns; with the coalesce, regeneration yields the nullable type the inspector already uses.Correctness fix
The old position lookup keyed on (schema, constraint name, column) without the table. Foreign key names are only unique per table, so two tables with a same-named FK on the same columns could get each other's column order:
c2was dumped asFOREIGN KEY (a, b) REFERENCES p (a, b), pointing at the primary key instead of the(b, a)unique constraint. New fixturetestdata/dump/issue_644_fk_column_orderfails before this change and passes after.Fixes #644
Fixes #654 (closed as duplicate)
Test plan
go test ./cmd/dump(full dump fixture suite, including the newTestDumpCommand_Issue644FKColumnOrder; red before the fix)go test ./internal/diff -run TestDiffFromFilesgo test ./ir/...PGSCHEMA_TEST_FILTER=<category>/ go test ./cmd -run TestPlanAndApplyforprivilege/,create_sequence/,create_view/,create_materialized_view/,create_table/go vet ./ir/...employeeand the 200-table reproduction are identical; query counts as in the table above🤖 Generated with Claude Code