AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Table Editor "Edit Table" Drops And Re-Adds The Primary Key On Saves That Don'T Change It

Supabase Studio Table Editor's updateTable compares primary key column names in display order with the server's key order, causing false positives for renaming or composite PK ordering, leading to unnecessary PK drop/re-add and failures when foreign keys depend on the PK.

mediumConfidence 90%Supabase-Studio

Origin Analysis

The comparison logic in updateTable relies on column names in display order, but primary_keys from the backend are returned in key order (e.g., (b, a) vs (a, b)). This causes the PK to be incorrectly flagged as changed, triggering a drop and recreate of the primary key constraint in separate transactions.
1. Open Supabase Studio Table Editor. 2. Select a table with a composite primary key whose key order differs from display order (e.g., PK (b, a), display columns a, b). 3. Rename a PK column or modify a description without changing the PK. 4. Save the table. 5. Observe that Studio attempts to drop and re-add the primary key. If foreign keys reference the PK, the save fails with 'cannot drop constraint ... other objects depend on it'; otherwise the PK is silently rebuilt and the order may change.

Fixing Code Block

// Replace PK change detection in updateTable (e.g., in TableEditor) function hasPrimaryKeyChanged( currentPkColumns: { id: string }[], nextPkColumns: { id: string }[] ): boolean { const currentIds = new Set(currentPkColumns.map(col => col.id)); const nextIds = new Set(nextPkColumns.map(col => col.id)); if (currentIds.size !== nextIds.size) return true; for (const id of currentIds) { if (!nextIds.has(id)) return true; } return false; } // Inside updateTable, before dropping/recreating PK: const existingPkColumnIds = existingPkColumns.map(col => col.id); const newPkColumnIds = newPkColumns.map(col => col.id); if (!hasPrimaryKeyChanged(existingPkColumnIds, newPkColumnIds)) { // Do not alter primary key constraint console.info('Primary key unchanged, skipping PK drop/add'); } else { // Proceed with ALTER TABLE to update PK using column ids, ideally in a single transaction await alterPrimaryKey(table, existingPkColumnIds, newPkColumnIds); }
The fix replaces name-order comparison with a set-based comparison of column IDs, which are stable across renames and display reordering. This prevents false positives and avoids unnecessary PK drops. The actual PK alteration (when needed) should be performed using column IDs and in a single transaction to avoid partial failures.

Edge Case Audit

This fix assumes column IDs are stable and unique across the table's lifetime; if columns are dropped and IDs reused, or if the frontend generates new IDs on rename, the comparison may still be incorrect. Concurrent edits on the same table can lead to stale comparisons; recommend server-side authoritative check. If a PK change is truly required, the ALTER TABLE must be executed in a transaction to avoid leaving the table without a primary key. Rollback: if this fix causes unexpected PK reconstruction, revert to the previous version, but first verify whether any affected tables have had their primary key order changed; manually restore the original constraint if necessary.

Ecosystem Topology