fix(coderd/database): allow same custom role name for different orgs (#21312)

Previously the `idx_custom_roles_name_lower` index prevented that.

A check constraint was also added to ensure the `organization_id` column cannot be set to the all-zero UUID.
This commit is contained in:
George K
2026-01-05 07:43:08 -08:00
committed by GitHub
parent 55cc6b807c
commit e10fceb23c
6 changed files with 49 additions and 3 deletions
@@ -0,0 +1,6 @@
-- Restore the original unique constraint (name only, no organization_id).
DROP INDEX IF EXISTS idx_custom_roles_name_lower_organization_id;
ALTER TABLE custom_roles DROP CONSTRAINT IF EXISTS organization_id_not_zero;
CREATE UNIQUE INDEX idx_custom_roles_name_lower ON custom_roles USING btree (LOWER(name));
@@ -0,0 +1,28 @@
-- Fix the unique index in `custom_roles` to allow the same role name
-- in different organizations. The original index only covered name,
-- but names don't have to be unique across different organizations.
--
-- Note: after fixing it, we end up with an almost-replica of the
-- existing `custom_roles_unique_key` constraint. That's unfortunate,
-- but since we can't define a constraint on an expression (e.g. lower()),
-- we'll have to keep both of them.
DROP INDEX IF EXISTS idx_custom_roles_name_lower;
-- Use `COALESCE` to handle `NULL` organization_id. Site-wide custom
-- roles are currently not used, but that can change in the future and
-- this will become necessary. And there are no performance implications.
--
-- Note: Using `NULLS NOT DISTINCT` instead of `COALESCE` here would
-- limit us to PG15+.
-- Paranoia check.
UPDATE custom_roles SET organization_id = NULL WHERE organization_id = '00000000-0000-0000-0000-000000000000';
ALTER TABLE custom_roles
ADD CONSTRAINT organization_id_not_zero
CHECK (organization_id <> '00000000-0000-0000-0000-000000000000'::uuid);
CREATE UNIQUE INDEX idx_custom_roles_name_lower_organization_id ON custom_roles USING btree (
LOWER(name),
COALESCE(organization_id, '00000000-0000-0000-0000-000000000000'::uuid)
);
@@ -0,0 +1,10 @@
-- Fixture for migration 000404_allow_same_role_name_in_different_orgs.
-- Inserts a custom role with an all-zero organization_id to ensure the
-- migration correctly normalizes such values.
INSERT INTO custom_roles (name, display_name, organization_id)
VALUES (
'custom-role-zero-org-id',
'Custom Role (Zero Org ID)',
'00000000-0000-0000-0000-000000000000'::uuid
)
ON CONFLICT DO NOTHING;