From 6d75e4e18ed68ced10c62c0dcbeed710ddad10c1 Mon Sep 17 00:00:00 2001
From: Alex Pooley <apooley@gitlab.com>
Date: Thu, 1 Apr 2021 18:58:13 +0000
Subject: [PATCH] Backfill traversal_ids for gitlab-org .com

---
 ...al_ids-for-production-gitlab-org-group.yml |  5 ++
 ..._traversal_ids_for_gitlab_org_group_com.rb | 88 +++++++++++++++++++
 db/schema_migrations/20210311045139           |  1 +
 3 files changed, 94 insertions(+)
 create mode 100644 changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml
 create mode 100644 db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb
 create mode 100644 db/schema_migrations/20210311045139

diff --git a/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml b/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml
new file mode 100644
index 0000000000000..fc438b5cc6b39
--- /dev/null
+++ b/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml
@@ -0,0 +1,5 @@
+---
+title: Backfill traversal_ids for gitlab-org .com
+merge_request: 57075
+author:
+type: performance
diff --git a/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb b/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb
new file mode 100644
index 0000000000000..8cef1f1cc2b36
--- /dev/null
+++ b/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+class SetTraversalIdsForGitlabOrgGroupCom < ActiveRecord::Migration[6.0]
+  include Gitlab::Database::MigrationHelpers
+
+  DOWNTIME = false
+
+  def up
+    return unless Gitlab.com?
+
+    # namespace ID 9970 is gitlab-org on .com
+    with_lock_retries do
+      execute(<<~SQL)
+        UPDATE
+          namespaces
+        SET
+          traversal_ids = cte.traversal_ids
+        FROM
+          (
+            WITH RECURSIVE cte(id, traversal_ids, cycle) AS (
+              VALUES
+                (9970, ARRAY[9970], false)
+              UNION ALL
+              SELECT
+                n.id,
+                cte.traversal_ids || n.id,
+                n.id = ANY(cte.traversal_ids)
+              FROM
+                namespaces n,
+                cte
+              WHERE
+                n.parent_id = cte.id
+                AND NOT cycle
+            )
+            SELECT
+              id,
+              traversal_ids
+            FROM
+              cte FOR
+            UPDATE
+              ) as cte
+        WHERE
+          namespaces.id = cte.id
+          AND namespaces.traversal_ids <> cte.traversal_ids
+      SQL
+    end
+  end
+
+  def down
+    return unless Gitlab.com?
+
+    # namespace ID 9970 is gitlab-org on .com
+    with_lock_retries do
+      execute(<<~SQL)
+        UPDATE
+          namespaces
+        SET
+          traversal_ids = '{}'
+        FROM
+          (
+            WITH RECURSIVE cte(id, traversal_ids, cycle) AS (
+              VALUES
+                (9970, ARRAY[9970], false)
+              UNION ALL
+              SELECT
+                n.id,
+                cte.traversal_ids || n.id,
+                n.id = ANY(cte.traversal_ids)
+              FROM
+                namespaces n,
+                cte
+              WHERE
+                n.parent_id = cte.id
+                AND NOT cycle
+            )
+            SELECT
+              id,
+              traversal_ids
+            FROM
+              cte FOR
+            UPDATE
+              ) as cte
+        WHERE
+          namespaces.id = cte.id
+      SQL
+    end
+  end
+end
diff --git a/db/schema_migrations/20210311045139 b/db/schema_migrations/20210311045139
new file mode 100644
index 0000000000000..71026c1b2afcf
--- /dev/null
+++ b/db/schema_migrations/20210311045139
@@ -0,0 +1 @@
+2387c8a5516aaf8bcf44c9bad45bfc9844d68d2c03330f67773ce046b21a7a6c
\ No newline at end of file
-- 
GitLab