Skip to content

fix(postgres): resolve cross-schema foreign key references - #1474

Merged
debba merged 1 commit into
TabularisDB:mainfrom
wuzi:fix/cross-schema-fk-ref-schema
Nov 12, 2026
Merged

debba merged 1 commit into
TabularisDB:mainfrom
wuzi:fix/cross-schema-fk-ref-schema

Conversation

@wuzi

@wuzi wuzi commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1473.

On PostgreSQL, a foreign key into another schema (billing.carry_forwards.organization_id → core.organizations.id) broke the Related Records panel with relation "billing.organizations" does not exist, and "Open referenced table" opened billing.organizations. The driver already selected the referenced schema but dropped it, so the frontend qualified ref_table with the source table's schema.

ForeignKey gains an optional ref_schema, filled by the built-in PostgreSQL driver in get_foreign_keys and get_all_foreign_keys_batch. The frontend resolves the referenced schema through one helper, getReferencedSchema (ref_schema, else the source schema), used by the Related Records query and by "Open referenced table". The panel now receives the tab's schema rather than the sidebar's, matching the schema its FK metadata was loaded with. MySQL and SQLite leave the field unset.

Plugin behaviour: ref_schema is optional and additive (#[serde(default)]) and documented in PLUGIN_GUIDE.md. Plugins that return it get the fix; plugins that don't keep today's behaviour of assuming the source schema. Navigation still passes a schema only when capabilities.schemas is true. The PostgreSQL plugin gets the field in TabularisDB/tabularis-postgresql-plugin#190; without it, its three FK parity tests diverge from the built-in driver.

Validation:

  • PostgreSQL integration suite, as run in CI: 199 passed. The cross-schema FK test now asserts ref_schema for the single and batch paths (replacing its TODO), and both FK golden files gain the field.
  • Parity suite with POSTGRES_PLUGIN_BIN set to the patched plugin: all FK parity tests pass. 22 unrelated parity tests (timing fields, column metadata) also fail against the released plugin on main.
  • Vitest: tests for getReferencedSchema and a cross-schema fetchReferencedRecord case that passes a capabilities object; the touched suites and editor page tests pass (170).
  • pnpm typecheck, eslint, prettier, rustfmt on touched files, and cargo check --no-default-features pass.
  • Manual: Tauri dev build with the patched plugin against a real multi-schema database; the panel loads the row from core.organizations.

Not changed here (same root cause, separate follow-ups): DDL generation emits REFERENCES without a schema, ER diagram edges match by table name only, and MySQL cross-database foreign keys.

@kilo-code-bot

kilo-code-bot Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Notes

  • Verified the PostgreSQL FK queries (single and batch) already select foreign_schema_name, so ref_schema is populated correctly in both paths.
  • All ForeignKey struct constructors (MySQL, SQLite, PostgreSQL, AI schema context test) are updated; the field is #[serde(default, skip_serializing_if = "Option::is_none")], which keeps plugin and golden-file compatibility.
  • getReferencedSchema falls back to the source schema, so plugins that don't report ref_schema behave as before. Navigation still gates on capabilities.schemas.
  • The Related Records panel now receives the tab's schema, which is consistent with the schema its FK metadata was loaded with.
  • Frontend unit tests, the Rust integration assertions and golden files cover the new behaviour. I did not run them, since this review is read-only.
Files Reviewed (15 files)
  • packages/web-ui/src/hooks/useReferencedRecord.ts
  • packages/web-ui/src/pages/Editor.tsx
  • packages/web-ui/src/types/schema.ts
  • packages/web-ui/src/utils/foreignKeys.ts
  • packages/web-ui/tests/hooks/useReferencedRecord.test.ts
  • packages/web-ui/tests/utils/foreignKeys.test.ts
  • plugins/PLUGIN_GUIDE.md
  • src-tauri/src/ai_schema_context_tests.rs
  • src-tauri/src/drivers/mysql/mod.rs
  • src-tauri/src/drivers/postgres/mod.rs
  • src-tauri/src/drivers/sqlite/mod.rs
  • src-tauri/src/models.rs
  • src-tauri/tests/postgres_integration/foreign_keys.rs
  • src-tauri/tests/postgres_integration/golden/get_foreign_keys_cross_schema.json
  • src-tauri/tests/postgres_integration/golden/get_foreign_keys_orders.json

Reviewed by claude-sonnet-5.5 · Input: 248 · Output: 2.4K · Cached: 277.4K

Review guidance: REVIEW.md from base branch main

@debba debba left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @wuzi, both for reporting #1473 and for fixing it! Putting the logic in a single tested helper, getReferencedSchema, and using it for both the Related Records lookup and "Open referenced table" keeps it tidy. I also appreciate that you documented ref_schema in PLUGIN_GUIDE.md, added the batch-path assertion in the Postgres integration test, and opened the matching plugin PR. Using activeTab?.schema ?? activeSchema for the Related Records panel fixes a second, quieter bug too. I ran the driver's FK queries against a PostgreSQL 16 database with cross-schema, composite and quoted-name FKs, and the referenced schema came back correctly in every case.

Since this is your first PR here: if you'd like to hang out with us, we'd be glad to see you on Discord: https://discord.com/invite/K2hmhfHRSt

Approving. Two small follow-ups:

  1. NewRowModal.tsx (not touched here) still loads the FK dropdown options from the source schema with quoteTableRef(fk.ref_table, activeDriver, activeSchema) and schema: activeSchema, so adding a row to a table with a cross-schema FK hits the same relation ... does not exist error. Using getReferencedSchema(fk, activeSchema) for both would close the last gap. Feel free to add it here if you have a minute.
  2. Optional: the Related Records header shows the bare table name. When a table with the same name exists in the source schema, showing ref_schema. only when it differs would make it clear which one you're looking at.

#1478 touches the same code, so I'll coordinate the two. I'll also do a manual pass in the app before merging.

@wuzi

wuzi commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

thanks for the review, @debba! Tabularis has become my daily driver for databases, so I’m glad to be able to contribute a little bit.

Sounds good, I will join the Discord and do the small follow-up changes.

@debba
debba merged commit 83d6dfb into TabularisDB:main Nov 12, 2026
15 checks passed
@wuzi
wuzi deleted the fix/cross-schema-fk-ref-schema branch November 12, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Related Records fails for foreign keys that reference another PostgreSQL schema

2 participants