Skip to content

Replace namespaces unique index on name and parent_id

What does this MR do and why?

This MR replaces existing unique index on namespaces table on name, parent_id columns with a unique index on name, parent_id, type columns.

Given that we currently only have nil and Group as namespace types and namespaces with type nil(which is a user namespace) cannot be a child of a Group because user namespaces cannot have a parent, new index will still keep the current functionality intact.

Why do we need the new index then?

There are 2 factors that force us to slightly change the unique index:

  1. We are working towards consolidating Projects and Namespaces (see &6473). For that we will introduce ProjectNamespace model, that will have a corresponding record in namespaces table for each Project. ProjectNamespace will have type=Project.
  2. Currently we do not allow 2 child groups to have the same name within a group, but we do allow a project to have the same name as any of the child groups if using a different path. Here is a screenshot to better illustrate what I mean:

Screenshot_2021-09-28_at_13.09.48

Even though on .com there are no such occurrences where a project in a group would have the same name as any 'child group' in that group, it is not impossible that there will be such cases on on-premise installs.

So slightly changing the index keeps both the current functionality and also allows us to add ProjectNamespace records to namespaces table even if a project would have the same name as some child group within its parent group. Which would not be possible with the current unique index just on name, parent_id columns

re #341814 (closed)

Database

UP

== 20210922172056 AddUniqueNamespacesIndexOnNameParentIdAndType: migrating ====
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:namespaces, [:name, :parent_id, :type], {:unique=>true, :name=>"index_namespaces_name_parent_id_type", :algorithm=>:concurrently})
   -> 0.0152s
-- execute("SET statement_timeout TO 0")
   -> 0.0007s
-- add_index(:namespaces, [:name, :parent_id, :type], {:unique=>true, :name=>"index_namespaces_name_parent_id_type", :algorithm=>:concurrently})
   -> 0.0065s
-- execute("RESET statement_timeout")
   -> 0.0010s
== 20210922172056 AddUniqueNamespacesIndexOnNameParentIdAndType: migrated (0.0280s)

== 20210922172156 DropUniqueNamespacesIndexOnNameAndParentId: migrating =======
-- transaction_open?()
   -> 0.0000s
-- indexes(:namespaces)
   -> 0.0111s
-- remove_index(:namespaces, {:algorithm=>:concurrently, :name=>"index_namespaces_on_name_and_parent_id"})
   -> 0.0031s
== 20210922172156 DropUniqueNamespacesIndexOnNameAndParentId: migrated (0.0159s)

DOWN

== 20210922172156 DropUniqueNamespacesIndexOnNameAndParentId: reverting =======
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:namespaces, [:name, :parent_id], {:unique=>true, :name=>"index_namespaces_on_name_and_parent_id", :algorithm=>:concurrently})
   -> 0.0161s
-- add_index(:namespaces, [:name, :parent_id], {:unique=>true, :name=>"index_namespaces_on_name_and_parent_id", :algorithm=>:concurrently})
   -> 0.0092s
== 20210922172156 DropUniqueNamespacesIndexOnNameAndParentId: reverted (0.0276s)

== 20210922172056 AddUniqueNamespacesIndexOnNameParentIdAndType: reverting ====
-- transaction_open?()
   -> 0.0000s
-- indexes(:namespaces)
   -> 0.0151s
-- remove_index(:namespaces, {:algorithm=>:concurrently, :name=>"index_namespaces_name_parent_id_type"})
   -> 0.0041s
== 20210922172056 AddUniqueNamespacesIndexOnNameParentIdAndType: reverted (0.0214s)

Screenshots or screen recordings

These are strongly recommended to assist reviewers and reduce the time to merge your change.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Mayra Cabrera

Merge request reports