Skip to content

Drop the foreign-key axis from the introspection model #78

Description

@Artmann

What's wrong

The introspection model carries a foreign-key axis that is collected three different ways, at three fidelities, and read by nobody — and the Postgres collection is wrong.

Collected everywhere

  • schema-provider.ts:36-53 — 18 lines of Postgres SQL, a separate round trip
  • schema-provider.ts:70-82 — MySQL
  • schema-provider.ts:95-109ForeignKeyRow plus a third parameter
  • schema-provider.ts:139-154 — a second keyed pass

Carried through adapter.ts:36-42,46, glue/api/schemas.ts:300-306,310, mysql-adapter.ts:36-37 (a serial second round trip), postgres-adapter.ts:279-283, and sqlite-adapter.ts:49-52,157-180 — one PRAGMA foreign_key_list per table, doubling SQLite's N+1 introspection.

Read by nobody

grep -rn "\.foreignKeys" src/ returns three hits: the provider's own write (:152) and two of its own tests.

DatabaseExplorer.tsx, database-explorer-search.ts, table-query.ts, postgres-identifier-fixer.ts, StatusBar.tsx and the query hooks touch only tables, columns, tableName, tableSchema, databaseName, serverVersion. No referencedTable* reader repo-wide; no doc mentions an ERD feature.

The one planned schema consumer (todo.md:228, schema-aware autocomplete via CodeMirror sql({schema, dialect})) takes a table→columns map and has no FK input.

And the Postgres data is wrong

:49-50 joins constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name with no ordinal correlation to kcu and no schema qualification.

A composite FK (a,b) → (x,y) yields the 2×2 cross product — four rows with two wrong column pairings — and two same-named constraints in different schemas cross-join too.

MySQL and SQLite are correct, so the three dialects silently disagree about what the field means. Never noticed, because never rendered.

Proposed change

TableInfo = { tableName, tableSchema, columns }.

transformToSchemaInfo(databaseName, columnRows) becomes a single-pass group-by plus a sort, with no join key and no second collection.

This deletes a whole dimension declared three times, collected three ways at three fidelities, read zero times — and deletes the buggy join rather than obliging someone to fix data nobody wants.

Scope

Core: delete both FK queries, ForeignKeyRow, the third parameter, the :139-154 loop, and the two FK tests (:50-97, :227-256).

The deletion is only type-safe once TableInfo.foreignKeys goes, which also touches adapter.ts:36-42,46; mysql-adapter.ts:37,41; postgres-adapter.ts:281,286; sqlite-adapter.ts:49-52,56,157-180; schemas.ts:300-306,310; and foreignKeys: [] fixtures in 4 test files.

~23 occurrences across 11 files, all deletions, no behaviour change for any shipped feature.

Risks

The wire shape shrinks and SchemaInfoDto.foreignKeys is currently required, so main and renderer must ship together — they do, it is one bundle, and the schema response is not persisted (mutations.ts:130 removes the cached query; nothing writes it to SQLite).

The real risk is product intent: if an ERD or relations panel is on the roadmap this is a delete-and-redo. Worth one confirmation before executing.

Validation

The two deleted tests cover exactly the deleted code; sqlite-adapter.test.ts asserts the PRAGMA-derived FKs; databases.test.ts / api.test.ts exercise the response shape.

No new tests — the remaining transform tests (grouping, sorting, MySQL is_primary_key 1/0, column mapping) hold unchanged, which is itself good evidence the axis is separable.


Found in a codebase-wide simplification audit (F-S05-a). Confidence: high that the field is unused and the Postgres query wrong; medium only on the product question.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions