mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
10eaab766f
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Bug fix ## What is the current behavior? In the Table Editor, the "View referencing record" arrow on a foreign key cell builds its filter from the table's `relationships` list. That list is one entry per source-by-target column combination, and the formatter takes the first entry whose source column matches the clicked cell, then filters the referenced table on that single target column. For a composite foreign key this fails in two ways: - The value from the clicked column can be applied to the wrong target column (whichever target column happens to be listed first for that source column). - Only one of the key columns is ever filtered on, so the peek and the "Open table" link return zero rows or too many rows. This is distinct from #41068 / #41080, which fixed the cartesian expansion in the shared `tables.ts` introspection query. The bug reproduces with that fix in place because the mis-pairing happens in Studio when building the filter. Reported by a customer via support. ### Reproduction Run this in the SQL editor. The referenced column list `(org_id, bucket_id)` is deliberately not in the referenced table's physical column order, which is what exposes the bug. ```sql create schema if not exists dcs; -- bucket_id declared first, org_id second create table dcs.org_metering_buckets ( bucket_id bigint not null, org_id bigint not null, primary key (org_id, bucket_id) ); create table dcs.machine_storage_usage_buckets ( org_id bigint not null, org_metering_bucket_id bigint not null, constraint machine_storage_usage_buckets_org_metering_bucket_fkey foreign key (org_id, org_metering_bucket_id) references dcs.org_metering_buckets (org_id, bucket_id) ); insert into dcs.org_metering_buckets (bucket_id, org_id) values (901, 1), (902, 1), (903, 2); insert into dcs.machine_storage_usage_buckets (org_id, org_metering_bucket_id) values (1, 901), (1, 902), (2, 903); ``` 1. Open `dcs.machine_storage_usage_buckets` in the Table Editor (select the `dcs` schema). 2. Hover the `org_id` cell on the row where `org_id = 2`. 3. Click the "View referencing record" arrow. 4. Click "Open table" in the popover. **Before this PR:** the popover shows "No results were returned". "Open table" opens `dcs.org_metering_buckets` with a single filter `bucket_id = 2`, which matches nothing. **After this PR:** the popover shows the one row `(bucket_id = 903, org_id = 2)`. "Open table" opens `dcs.org_metering_buckets` with two filters, `org_id = 2` and `bucket_id = 903`, and the URL carries two `filter=` params. Clicking the arrow on the `org_metering_bucket_id` cell of the same row produces the same result. Extra checks worth doing while you are there: - Set one of the two key columns to NULL on a row. The arrow should disappear for both key cells on that row, since a row with a null key column does not reference anything under MATCH SIMPLE. - A single-column foreign key (any existing table) should behave exactly as before. ## What is the new behavior? - New `ForeignKeyFormatter.utils.ts` with two pure functions. `findColumnForeignKeyConstraint` locates the constraint on the current table that contains the clicked column. `getReferencingRecordFilters` pairs each source column with the target column at the same ordinal position and builds one equality filter per pair from the row's values, keeping the existing bytea-to-hex handling per column. It returns no filters when any key column is null. - `ForeignKeyFormatter` now reads the foreign key constraints query, which returns ordinally paired source and target column arrays, instead of the `relationships` list. The grid already fetches that query for the same schema, so it is served from the React Query cache. - `ReferenceRecordPeek` takes a `filters` array instead of a single column and value. Both the peek query and the "Open table" link use the full set, and the link emits one URI-encoded `filter=` param per column. - Unit tests cover the reproduction above, single-column keys, bytea values, null and missing values, falsy-but-valid values such as `0`, and malformed constraints. ## Additional context The table-editor introspection SQL in `packages/pg-meta/src/sql/studio/table-editor/table.ts` and `tables-paginated.ts` still expands composite foreign keys as a cartesian product. #41080 only fixed the shared `tables.ts` query. The arrow no longer depends on that data, but it can still mislabel the referenced column elsewhere in Studio, so that is left for a follow-up rather than widening this change into pg-meta SQL. Before: <img width="836" height="504" alt="Screenshot 2026-09-14 at 11 22 49" src="https://github.com/user-attachments/assets/4645d64f-9bcb-44b0-b5b1-ab11ba7436db" /> After: <img width="873" height="570" alt="Screenshot 2026-09-14 at 11 23 14" src="https://github.com/user-attachments/assets/f2c47121-fd75-4efe-a370-28015c1b674e" /> 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01SkH86UV1KD4Xs5k9vt43tW <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved foreign-key record previews to correctly identify referenced records across schemas and tables. * Added support for composite foreign keys, ensuring previews and “Open table” links apply all required column filters. * Improved handling of binary values and incomplete or null foreign-key data. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>