From 14188b2061958bbdc033a9237cc0b1ba2ad6cc7e Mon Sep 17 00:00:00 2001 From: George Koltsov Date: Wed, 1 Oct 2025 14:29:29 +0100 Subject: [PATCH 1/3] Backfill jira_tracker_data and validate not null constraint --- ...ta_index_on_id_group_id_organization_id.rb | 21 ++++ ..._index_on_id_project_id_organization_id.rb | 21 ++++ ...ata_multiple_column_not_null_constraint.rb | 25 ++++ ...group_jira_tracker_data_organization_id.rb | 24 ++++ ...oject_jira_tracker_data_organization_id.rb | 24 ++++ ...ata_multiple_column_not_null_constraint.rb | 21 ++++ ...ta_index_on_id_group_id_organization_id.rb | 21 ++++ ..._index_on_id_project_id_organization_id.rb | 21 ++++ db/schema_migrations/20250930134216 | 1 + db/schema_migrations/20250930134220 | 1 + db/schema_migrations/20250930134225 | 1 + db/schema_migrations/20250930134230 | 1 + db/schema_migrations/20250930134235 | 1 + db/schema_migrations/20250930134240 | 1 + db/schema_migrations/20250930134245 | 1 + db/schema_migrations/20250930134250 | 1 + db/structure.sql | 3 +- ..._jira_tracker_data_organization_id_spec.rb | 107 +++++++++++++++++ ..._jira_tracker_data_organization_id_spec.rb | 108 ++++++++++++++++++ 19 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb create mode 100644 db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb create mode 100644 db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb create mode 100644 db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb create mode 100644 db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb create mode 100644 db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb create mode 100644 db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb create mode 100644 db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb create mode 100644 db/schema_migrations/20250930134216 create mode 100644 db/schema_migrations/20250930134220 create mode 100644 db/schema_migrations/20250930134225 create mode 100644 db/schema_migrations/20250930134230 create mode 100644 db/schema_migrations/20250930134235 create mode 100644 db/schema_migrations/20250930134240 create mode 100644 db/schema_migrations/20250930134245 create mode 100644 db/schema_migrations/20250930134250 create mode 100644 spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb create mode 100644 spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb diff --git a/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb new file mode 100644 index 00000000000000..3fdc9f4ac7a629 --- /dev/null +++ b/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataIndexOnIdGroupIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_group_id_organization_id' + + def up + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'group_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end +end diff --git a/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb new file mode 100644 index 00000000000000..4b6dc36a06f121 --- /dev/null +++ b/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' + + def up + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end +end diff --git a/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb new file mode 100644 index 00000000000000..e387a8eec290e1 --- /dev/null +++ b/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + def up + add_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id, + validate: false + ) + end + + def down + remove_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id + ) + end +end diff --git a/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb b/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb new file mode 100644 index 00000000000000..61a9d1a34fe5e4 --- /dev/null +++ b/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class BackfillGroupJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + def up + jira_tracker_data = define_batchable_model('jira_tracker_data') + + jira_tracker_data + .where.not(group_id: nil) + .where.not(organization_id: nil) + .each_batch(of: BATCH_SIZE) do |batch| + batch.update_all(organization_id: nil) + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb b/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb new file mode 100644 index 00000000000000..8ae57284a532da --- /dev/null +++ b/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class BackfillProjectJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + def up + jira_tracker_data = define_batchable_model('jira_tracker_data') + + jira_tracker_data + .where.not(project_id: nil) + .where.not(organization_id: nil) + .each_batch(of: BATCH_SIZE) do |batch| + batch.update_all(organization_id: nil) + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb new file mode 100644 index 00000000000000..7ffd86ab6c4d5d --- /dev/null +++ b/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class ValidateJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] + milestone '18.5' + + CONSTRAINT_NAME = 'check_eca1fbd6bd' + + def up + validate_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id, + constraint_name: CONSTRAINT_NAME + ) + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb new file mode 100644 index 00000000000000..a4403aeb05532c --- /dev/null +++ b/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveJiraTrackerDataIndexOnIdGroupIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_group_id_organization_id' + + def up + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end + + def down + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'group_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end +end diff --git a/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb new file mode 100644 index 00000000000000..feeeeb1f8a0c93 --- /dev/null +++ b/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' + + def up + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end + + def down + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end +end diff --git a/db/schema_migrations/20250930134216 b/db/schema_migrations/20250930134216 new file mode 100644 index 00000000000000..f52bb0ab80919f --- /dev/null +++ b/db/schema_migrations/20250930134216 @@ -0,0 +1 @@ +40fe1d93503a054bb7f11d929ff324b02a757421ce6e9da6b194334049a8f7b2 \ No newline at end of file diff --git a/db/schema_migrations/20250930134220 b/db/schema_migrations/20250930134220 new file mode 100644 index 00000000000000..08429ed19b55ec --- /dev/null +++ b/db/schema_migrations/20250930134220 @@ -0,0 +1 @@ +35b61b57731eecefa8495ff06583be305d194cdee0a623607c44daa8f8a2d6ca \ No newline at end of file diff --git a/db/schema_migrations/20250930134225 b/db/schema_migrations/20250930134225 new file mode 100644 index 00000000000000..d3c2d22f6b4d8d --- /dev/null +++ b/db/schema_migrations/20250930134225 @@ -0,0 +1 @@ +ab306d746698954a0fa9946d435ecf20dc89d0c38c3e1c798469651735ebfe02 \ No newline at end of file diff --git a/db/schema_migrations/20250930134230 b/db/schema_migrations/20250930134230 new file mode 100644 index 00000000000000..3d31e1fe20df9d --- /dev/null +++ b/db/schema_migrations/20250930134230 @@ -0,0 +1 @@ +1a184fba7636c37e77d7b9fe19eb2ae207d4bef93abcbe8fd31b0bf8e920e36e \ No newline at end of file diff --git a/db/schema_migrations/20250930134235 b/db/schema_migrations/20250930134235 new file mode 100644 index 00000000000000..968c51ef62e114 --- /dev/null +++ b/db/schema_migrations/20250930134235 @@ -0,0 +1 @@ +983bf2a71e0a4cd564bfd90284c306af41f6b62d9984ad4c7a60aa96f00213b0 \ No newline at end of file diff --git a/db/schema_migrations/20250930134240 b/db/schema_migrations/20250930134240 new file mode 100644 index 00000000000000..91b37da91dab5d --- /dev/null +++ b/db/schema_migrations/20250930134240 @@ -0,0 +1 @@ +9875bf5a8b745cbb8ed4ce512417dc489b2acf510e061f479538b9b244597233 \ No newline at end of file diff --git a/db/schema_migrations/20250930134245 b/db/schema_migrations/20250930134245 new file mode 100644 index 00000000000000..676657eec49961 --- /dev/null +++ b/db/schema_migrations/20250930134245 @@ -0,0 +1 @@ +c2ff243078391f0b2ccf1319687ed4d8c9c55a8b5d271cc650c213428185e8b3 \ No newline at end of file diff --git a/db/schema_migrations/20250930134250 b/db/schema_migrations/20250930134250 new file mode 100644 index 00000000000000..e6c7d47ee28445 --- /dev/null +++ b/db/schema_migrations/20250930134250 @@ -0,0 +1 @@ +f498697a2983c0f2c3ffabe1b8af5c525a04f464cf2b915edde0e8c79b583990 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index bb047bbf388c78..6badac2b8e3d34 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -18877,7 +18877,8 @@ CREATE TABLE jira_tracker_data ( CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255)), CONSTRAINT check_4cc5bbc801 CHECK ((char_length(jira_issue_prefix) <= 255)), CONSTRAINT check_9863a0a5fd CHECK ((char_length(jira_issue_regex) <= 255)), - CONSTRAINT check_b5ab881f50 CHECK ((char_length(jira_allowed_statuses_string) <= 1024)) + CONSTRAINT check_b5ab881f50 CHECK ((char_length(jira_allowed_statuses_string) <= 1024)), + CONSTRAINT check_eca1fbd6bd CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1)) ); CREATE SEQUENCE jira_tracker_data_id_seq diff --git a/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb b/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb new file mode 100644 index 00000000000000..e8607e8a0d8a04 --- /dev/null +++ b/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillGroupJiraTrackerDataOrganizationId, feature_category: :integrations do + let(:organizations) { table(:organizations) } + let(:jira_tracker_data) { table(:jira_tracker_data) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:integrations) { table(:integrations) } + + let!(:organization) { organizations.create!(id: 1, name: 'Default', path: 'default') } + let!(:group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + + let!(:project) do + projects.create!( + name: 'baz', + path: 'baz', + organization_id: 1, + namespace_id: group.id, + project_namespace_id: group.id + ) + end + + let!(:integration) do + integrations.create!(group_id: group.id, type_new: 'Integrations::Jira') + end + + let(:tracker_data_to_backfill) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:another_tracker_data_to_backfill) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:valid_tracker_data) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id) + end + + let(:project_tracker_data) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id) + end + + let(:organization_tracker_data) do + instance_integration = integrations.create!( + instance: true, + organization_id: organization.id, + type_new: 'Integrations::Jira' + ) + + jira_tracker_data.create!(organization_id: organization.id, integration_id: instance_integration.id) + end + + before do + ApplicationRecord.connection.execute('ALTER TABLE jira_tracker_data DROP CONSTRAINT IF EXISTS check_eca1fbd6bd;') + end + + after do + ApplicationRecord + .connection + .execute( + 'ALTER TABLE jira_tracker_data ADD CONSTRAINT check_eca1fbd6bd ' \ + 'CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1)) NOT VALID;' + ) + end + + describe "#up" do + it 'sets organization_id to nil for group jira_tracker_data that have it' do + expect(tracker_data_to_backfill.group_id).to eq(group.id) + expect(tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(another_tracker_data_to_backfill.group_id).to eq(group.id) + expect(another_tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(valid_tracker_data.group_id).to eq(group.id) + expect(valid_tracker_data.organization_id).to be_nil + + expect(project_tracker_data.project_id).to eq(project.id) + expect(project_tracker_data.organization_id).to be_nil + + expect(organization_tracker_data.organization_id).to eq(organization.id) + expect(organization_tracker_data.project_id).to be_nil + expect(organization_tracker_data.group_id).to be_nil + + migrate! + + expect(tracker_data_to_backfill.reload.group_id).to eq(group.id) + expect(tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(another_tracker_data_to_backfill.reload.group_id).to eq(group.id) + expect(another_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(valid_tracker_data.reload.group_id).to eq(group.id) + expect(valid_tracker_data.reload.organization_id).to be_nil + + expect(project_tracker_data.reload.project_id).to eq(project.id) + expect(project_tracker_data.reload.organization_id).to be_nil + + expect(organization_tracker_data.reload.organization_id).to eq(organization.id) + expect(organization_tracker_data.reload.project_id).to be_nil + expect(organization_tracker_data.reload.group_id).to be_nil + end + end +end diff --git a/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb b/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb new file mode 100644 index 00000000000000..9b23fc3671c100 --- /dev/null +++ b/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillProjectJiraTrackerDataOrganizationId, feature_category: :integrations do + let(:organizations) { table(:organizations) } + let(:jira_tracker_data) { table(:jira_tracker_data) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:integrations) { table(:integrations) } + + let!(:organization) { organizations.create!(id: 1, name: 'Default', path: 'default') } + let!(:group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + + let!(:project) do + projects.create!( + name: 'baz', + path: 'baz', + organization_id: 1, + namespace_id: group.id, + project_namespace_id: group.id + ) + end + + let!(:integration) do + integrations.create!(project_id: project.id, type_new: 'Integrations::Jira') + end + + let(:tracker_data_to_backfill) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:another_tracker_data_to_backfill) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:valid_tracker_data) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id) + end + + let(:group_tracker_data) do + group_integration = integrations.create!(group_id: group.id, type_new: 'Integrations::Jira') + jira_tracker_data.create!(group_id: group.id, integration_id: group_integration.id) + end + + let(:organization_tracker_data) do + instance_integration = integrations.create!( + instance: true, + organization_id: organization.id, + type_new: 'Integrations::Jira' + ) + + jira_tracker_data.create!(organization_id: organization.id, integration_id: instance_integration.id) + end + + before do + ApplicationRecord.connection.execute('ALTER TABLE jira_tracker_data DROP CONSTRAINT IF EXISTS check_eca1fbd6bd;') + end + + after do + ApplicationRecord + .connection + .execute( + 'ALTER TABLE jira_tracker_data ADD CONSTRAINT check_eca1fbd6bd ' \ + 'CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1));' + ) + end + + describe "#up" do + it 'sets organization_id to nil for project jira_tracker_data that have it' do + expect(tracker_data_to_backfill.project_id).to eq(project.id) + expect(tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(another_tracker_data_to_backfill.project_id).to eq(project.id) + expect(another_tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(valid_tracker_data.project_id).to eq(project.id) + expect(valid_tracker_data.organization_id).to be_nil + + expect(group_tracker_data.group_id).to eq(group.id) + expect(group_tracker_data.organization_id).to be_nil + + expect(organization_tracker_data.organization_id).to eq(organization.id) + expect(organization_tracker_data.project_id).to be_nil + expect(organization_tracker_data.group_id).to be_nil + + migrate! + + expect(tracker_data_to_backfill.reload.project_id).to eq(project.id) + expect(tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(another_tracker_data_to_backfill.reload.project_id).to eq(project.id) + expect(another_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(valid_tracker_data.reload.project_id).to eq(project.id) + expect(valid_tracker_data.reload.organization_id).to be_nil + + expect(group_tracker_data.reload.group_id).to eq(group.id) + expect(group_tracker_data.reload.organization_id).to be_nil + + expect(organization_tracker_data.reload.organization_id).to eq(organization.id) + expect(organization_tracker_data.reload.project_id).to be_nil + expect(organization_tracker_data.reload.group_id).to be_nil + end + end +end -- GitLab From 89d8fc438c2024207a5e9c338e5d31ddbda561e3 Mon Sep 17 00:00:00 2001 From: George Koltsov Date: Mon, 6 Oct 2025 11:13:21 +0100 Subject: [PATCH 2/3] Update yml sharding key --- db/docs/jira_tracker_data.yml | 5 ++++- spec/lib/gitlab/database/sharding_key_spec.rb | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/db/docs/jira_tracker_data.yml b/db/docs/jira_tracker_data.yml index 2dbf419e26f771..4fd19fd7c6666e 100644 --- a/db/docs/jira_tracker_data.yml +++ b/db/docs/jira_tracker_data.yml @@ -8,5 +8,8 @@ description: Data related to the Jira integration. introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/1f332ae8da994509232c7601074b25514ad23c52 milestone: '12.0' gitlab_schema: gitlab_main_org -sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/558259 table_size: small +sharding_key: + project_id: projects + group_id: namespaces + organization_id: organizations diff --git a/spec/lib/gitlab/database/sharding_key_spec.rb b/spec/lib/gitlab/database/sharding_key_spec.rb index 7a6fab50a90157..c0bb564f95751d 100644 --- a/spec/lib/gitlab/database/sharding_key_spec.rb +++ b/spec/lib/gitlab/database/sharding_key_spec.rb @@ -317,7 +317,6 @@ "ci_runner_taggings_group_type" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549027", "ci_runner_taggings_project_type" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549028", "customer_relations_contacts" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549029", - "jira_tracker_data" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549032", "abuse_reports" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553435", "abuse_report_labels" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553427", "abuse_report_events" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553429", -- GitLab From a02f7d95819c61c9ca9c9529b90d0b7eadc8c2e8 Mon Sep 17 00:00:00 2001 From: George Koltsov Date: Wed, 22 Oct 2025 16:39:51 +0100 Subject: [PATCH 3/3] Add one more backfill to set sharding keys --- ...tracker_data_index_on_null_sharding_key.rb | 21 ++++ ...a_index_on_id_group_id_organization_id.rb} | 0 ...index_on_id_project_id_organization_id.rb} | 2 +- ...ta_multiple_column_not_null_constraint.rb} | 2 +- ...ill_jira_tracker_data_null_sharding_key.rb | 35 ++++++ ...roup_jira_tracker_data_organization_id.rb} | 2 +- ...ject_jira_tracker_data_organization_id.rb} | 2 +- ...ta_multiple_column_not_null_constraint.rb} | 2 +- ...a_index_on_id_group_id_organization_id.rb} | 2 +- ...index_on_id_project_id_organization_id.rb} | 2 +- ...tracker_data_index_on_null_sharding_key.rb | 21 ++++ db/schema_migrations/20250930134216 | 1 - db/schema_migrations/20250930134220 | 1 - db/schema_migrations/20250930134225 | 1 - db/schema_migrations/20250930134230 | 1 - db/schema_migrations/20250930134235 | 1 - db/schema_migrations/20250930134240 | 1 - db/schema_migrations/20250930134245 | 1 - db/schema_migrations/20250930134250 | 1 - db/schema_migrations/20251020115917 | 1 + db/schema_migrations/20251020115921 | 1 + db/schema_migrations/20251020115924 | 1 + db/schema_migrations/20251020115927 | 1 + db/schema_migrations/20251020115929 | 1 + db/schema_migrations/20251020115932 | 1 + db/schema_migrations/20251020115936 | 1 + db/schema_migrations/20251020115938 | 1 + db/schema_migrations/20251020115941 | 1 + db/schema_migrations/20251020115945 | 1 + db/schema_migrations/20251020115950 | 1 + ...ira_tracker_data_null_sharding_key_spec.rb | 110 ++++++++++++++++++ 31 files changed, 205 insertions(+), 15 deletions(-) create mode 100644 db/post_migrate/20251020115917_add_jira_tracker_data_index_on_null_sharding_key.rb rename db/post_migrate/{20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb => 20251020115921_add_jira_tracker_data_index_on_id_group_id_organization_id.rb} (100%) rename db/post_migrate/{20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb => 20251020115924_add_jira_tracker_data_index_on_id_project_id_organization_id.rb} (96%) rename db/post_migrate/{20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb => 20251020115927_add_jira_tracker_data_multiple_column_not_null_constraint.rb} (96%) create mode 100644 db/post_migrate/20251020115929_backfill_jira_tracker_data_null_sharding_key.rb rename db/post_migrate/{20250930134230_backfill_group_jira_tracker_data_organization_id.rb => 20251020115932_backfill_group_jira_tracker_data_organization_id.rb} (96%) rename db/post_migrate/{20250930134235_backfill_project_jira_tracker_data_organization_id.rb => 20251020115936_backfill_project_jira_tracker_data_organization_id.rb} (96%) rename db/post_migrate/{20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb => 20251020115938_validate_jira_tracker_data_multiple_column_not_null_constraint.rb} (95%) rename db/post_migrate/{20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb => 20251020115941_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb} (96%) rename db/post_migrate/{20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb => 20251020115945_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb} (96%) create mode 100644 db/post_migrate/20251020115950_remove_jira_tracker_data_index_on_null_sharding_key.rb delete mode 100644 db/schema_migrations/20250930134216 delete mode 100644 db/schema_migrations/20250930134220 delete mode 100644 db/schema_migrations/20250930134225 delete mode 100644 db/schema_migrations/20250930134230 delete mode 100644 db/schema_migrations/20250930134235 delete mode 100644 db/schema_migrations/20250930134240 delete mode 100644 db/schema_migrations/20250930134245 delete mode 100644 db/schema_migrations/20250930134250 create mode 100644 db/schema_migrations/20251020115917 create mode 100644 db/schema_migrations/20251020115921 create mode 100644 db/schema_migrations/20251020115924 create mode 100644 db/schema_migrations/20251020115927 create mode 100644 db/schema_migrations/20251020115929 create mode 100644 db/schema_migrations/20251020115932 create mode 100644 db/schema_migrations/20251020115936 create mode 100644 db/schema_migrations/20251020115938 create mode 100644 db/schema_migrations/20251020115941 create mode 100644 db/schema_migrations/20251020115945 create mode 100644 db/schema_migrations/20251020115950 create mode 100644 spec/migrations/backfill_jira_tracker_data_null_sharding_key_spec.rb diff --git a/db/post_migrate/20251020115917_add_jira_tracker_data_index_on_null_sharding_key.rb b/db/post_migrate/20251020115917_add_jira_tracker_data_index_on_null_sharding_key.rb new file mode 100644 index 00000000000000..1ef15716926158 --- /dev/null +++ b/db/post_migrate/20251020115917_add_jira_tracker_data_index_on_null_sharding_key.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataIndexOnNullShardingKey < Gitlab::Database::Migration[2.3] + milestone '18.6' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_null_sharding_key' + + def up + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NULL AND group_id IS NULL AND organization_id IS NULL', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end +end diff --git a/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20251020115921_add_jira_tracker_data_index_on_id_group_id_organization_id.rb similarity index 100% rename from db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb rename to db/post_migrate/20251020115921_add_jira_tracker_data_index_on_id_group_id_organization_id.rb diff --git a/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20251020115924_add_jira_tracker_data_index_on_id_project_id_organization_id.rb similarity index 96% rename from db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb rename to db/post_migrate/20251020115924_add_jira_tracker_data_index_on_id_project_id_organization_id.rb index 4b6dc36a06f121..62d39914f73175 100644 --- a/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb +++ b/db/post_migrate/20251020115924_add_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AddJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' disable_ddl_transaction! INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' diff --git a/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20251020115927_add_jira_tracker_data_multiple_column_not_null_constraint.rb similarity index 96% rename from db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb rename to db/post_migrate/20251020115927_add_jira_tracker_data_multiple_column_not_null_constraint.rb index e387a8eec290e1..f9f4438749c3da 100644 --- a/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb +++ b/db/post_migrate/20251020115927_add_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AddJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' disable_ddl_transaction! def up diff --git a/db/post_migrate/20251020115929_backfill_jira_tracker_data_null_sharding_key.rb b/db/post_migrate/20251020115929_backfill_jira_tracker_data_null_sharding_key.rb new file mode 100644 index 00000000000000..5967c7b41edd8e --- /dev/null +++ b/db/post_migrate/20251020115929_backfill_jira_tracker_data_null_sharding_key.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class BackfillJiraTrackerDataNullShardingKey < Gitlab::Database::Migration[2.3] + milestone '18.6' + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + def up + jira_tracker_data_model = define_batchable_model('jira_tracker_data') + integrations_model = define_batchable_model('integrations') + + jira_tracker_data_model + .where(group_id: nil, project_id: nil, organization_id: nil) + .each_batch(of: BATCH_SIZE) do |batch| + integration_ids = batch.pluck(:integration_id) + integrations = integrations_model.where(id: integration_ids).index_by(&:id) + + batch.each do |record| + integration = integrations[record.integration_id] + + record.update( + project_id: integration.project_id, + group_id: integration.group_id, + organization_id: integration.organization_id + ) + end + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb b/db/post_migrate/20251020115932_backfill_group_jira_tracker_data_organization_id.rb similarity index 96% rename from db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb rename to db/post_migrate/20251020115932_backfill_group_jira_tracker_data_organization_id.rb index 61a9d1a34fe5e4..2c6a10d8e67290 100644 --- a/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb +++ b/db/post_migrate/20251020115932_backfill_group_jira_tracker_data_organization_id.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class BackfillGroupJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' restrict_gitlab_migration gitlab_schema: :gitlab_main_org disable_ddl_transaction! diff --git a/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb b/db/post_migrate/20251020115936_backfill_project_jira_tracker_data_organization_id.rb similarity index 96% rename from db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb rename to db/post_migrate/20251020115936_backfill_project_jira_tracker_data_organization_id.rb index 8ae57284a532da..1f377b587a25db 100644 --- a/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb +++ b/db/post_migrate/20251020115936_backfill_project_jira_tracker_data_organization_id.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class BackfillProjectJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' restrict_gitlab_migration gitlab_schema: :gitlab_main_org disable_ddl_transaction! diff --git a/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20251020115938_validate_jira_tracker_data_multiple_column_not_null_constraint.rb similarity index 95% rename from db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb rename to db/post_migrate/20251020115938_validate_jira_tracker_data_multiple_column_not_null_constraint.rb index 7ffd86ab6c4d5d..56daf2952ee75e 100644 --- a/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb +++ b/db/post_migrate/20251020115938_validate_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ValidateJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' CONSTRAINT_NAME = 'check_eca1fbd6bd' diff --git a/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20251020115941_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb similarity index 96% rename from db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb rename to db/post_migrate/20251020115941_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb index a4403aeb05532c..b902e8da0a3995 100644 --- a/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb +++ b/db/post_migrate/20251020115941_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class RemoveJiraTrackerDataIndexOnIdGroupIdOrganizationId < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' disable_ddl_transaction! INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_group_id_organization_id' diff --git a/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20251020115945_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb similarity index 96% rename from db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb rename to db/post_migrate/20251020115945_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb index feeeeb1f8a0c93..d867710af6c23b 100644 --- a/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb +++ b/db/post_migrate/20251020115945_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class RemoveJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] - milestone '18.5' + milestone '18.6' disable_ddl_transaction! INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' diff --git a/db/post_migrate/20251020115950_remove_jira_tracker_data_index_on_null_sharding_key.rb b/db/post_migrate/20251020115950_remove_jira_tracker_data_index_on_null_sharding_key.rb new file mode 100644 index 00000000000000..8be29fe98116fa --- /dev/null +++ b/db/post_migrate/20251020115950_remove_jira_tracker_data_index_on_null_sharding_key.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveJiraTrackerDataIndexOnNullShardingKey < Gitlab::Database::Migration[2.3] + milestone '18.6' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_null_sharding_key' + + def up + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end + + def down + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NULL AND group_id IS NULL AND organization_id IS NULL', + name: INDEX_NAME + ) + end +end diff --git a/db/schema_migrations/20250930134216 b/db/schema_migrations/20250930134216 deleted file mode 100644 index f52bb0ab80919f..00000000000000 --- a/db/schema_migrations/20250930134216 +++ /dev/null @@ -1 +0,0 @@ -40fe1d93503a054bb7f11d929ff324b02a757421ce6e9da6b194334049a8f7b2 \ No newline at end of file diff --git a/db/schema_migrations/20250930134220 b/db/schema_migrations/20250930134220 deleted file mode 100644 index 08429ed19b55ec..00000000000000 --- a/db/schema_migrations/20250930134220 +++ /dev/null @@ -1 +0,0 @@ -35b61b57731eecefa8495ff06583be305d194cdee0a623607c44daa8f8a2d6ca \ No newline at end of file diff --git a/db/schema_migrations/20250930134225 b/db/schema_migrations/20250930134225 deleted file mode 100644 index d3c2d22f6b4d8d..00000000000000 --- a/db/schema_migrations/20250930134225 +++ /dev/null @@ -1 +0,0 @@ -ab306d746698954a0fa9946d435ecf20dc89d0c38c3e1c798469651735ebfe02 \ No newline at end of file diff --git a/db/schema_migrations/20250930134230 b/db/schema_migrations/20250930134230 deleted file mode 100644 index 3d31e1fe20df9d..00000000000000 --- a/db/schema_migrations/20250930134230 +++ /dev/null @@ -1 +0,0 @@ -1a184fba7636c37e77d7b9fe19eb2ae207d4bef93abcbe8fd31b0bf8e920e36e \ No newline at end of file diff --git a/db/schema_migrations/20250930134235 b/db/schema_migrations/20250930134235 deleted file mode 100644 index 968c51ef62e114..00000000000000 --- a/db/schema_migrations/20250930134235 +++ /dev/null @@ -1 +0,0 @@ -983bf2a71e0a4cd564bfd90284c306af41f6b62d9984ad4c7a60aa96f00213b0 \ No newline at end of file diff --git a/db/schema_migrations/20250930134240 b/db/schema_migrations/20250930134240 deleted file mode 100644 index 91b37da91dab5d..00000000000000 --- a/db/schema_migrations/20250930134240 +++ /dev/null @@ -1 +0,0 @@ -9875bf5a8b745cbb8ed4ce512417dc489b2acf510e061f479538b9b244597233 \ No newline at end of file diff --git a/db/schema_migrations/20250930134245 b/db/schema_migrations/20250930134245 deleted file mode 100644 index 676657eec49961..00000000000000 --- a/db/schema_migrations/20250930134245 +++ /dev/null @@ -1 +0,0 @@ -c2ff243078391f0b2ccf1319687ed4d8c9c55a8b5d271cc650c213428185e8b3 \ No newline at end of file diff --git a/db/schema_migrations/20250930134250 b/db/schema_migrations/20250930134250 deleted file mode 100644 index e6c7d47ee28445..00000000000000 --- a/db/schema_migrations/20250930134250 +++ /dev/null @@ -1 +0,0 @@ -f498697a2983c0f2c3ffabe1b8af5c525a04f464cf2b915edde0e8c79b583990 \ No newline at end of file diff --git a/db/schema_migrations/20251020115917 b/db/schema_migrations/20251020115917 new file mode 100644 index 00000000000000..d531cdb16f2d17 --- /dev/null +++ b/db/schema_migrations/20251020115917 @@ -0,0 +1 @@ +f9e06131f95dbd5241148e2f0970d49df5a578ec518f38a29dc4d5e38c151fb6 \ No newline at end of file diff --git a/db/schema_migrations/20251020115921 b/db/schema_migrations/20251020115921 new file mode 100644 index 00000000000000..25d7cd5ff7d5fe --- /dev/null +++ b/db/schema_migrations/20251020115921 @@ -0,0 +1 @@ +e744d503aa43a63969db0fb1bea5bc0958fe6b8a03355f9e2eb71e6e614cfb3c \ No newline at end of file diff --git a/db/schema_migrations/20251020115924 b/db/schema_migrations/20251020115924 new file mode 100644 index 00000000000000..df523b33608bed --- /dev/null +++ b/db/schema_migrations/20251020115924 @@ -0,0 +1 @@ +2febf44807f0eb5fe46ba670a47adae38ec559f1968e85025cee7f55dfe53dcc \ No newline at end of file diff --git a/db/schema_migrations/20251020115927 b/db/schema_migrations/20251020115927 new file mode 100644 index 00000000000000..676d53c0f02269 --- /dev/null +++ b/db/schema_migrations/20251020115927 @@ -0,0 +1 @@ +9f9b01edf4d6681b86d987a79cb68222ead4a558a5c896927f55588ae19297c5 \ No newline at end of file diff --git a/db/schema_migrations/20251020115929 b/db/schema_migrations/20251020115929 new file mode 100644 index 00000000000000..835928128ba754 --- /dev/null +++ b/db/schema_migrations/20251020115929 @@ -0,0 +1 @@ +fefd67fcc04d36b257eaf6b572d72fb5738bc811392ac437c5b821b3bbefc292 \ No newline at end of file diff --git a/db/schema_migrations/20251020115932 b/db/schema_migrations/20251020115932 new file mode 100644 index 00000000000000..b0216860b9e337 --- /dev/null +++ b/db/schema_migrations/20251020115932 @@ -0,0 +1 @@ +d5cd59d6326e83e4e9633e8cd8bf32ba8d273ce1040515ec8580c2cf6cd2d495 \ No newline at end of file diff --git a/db/schema_migrations/20251020115936 b/db/schema_migrations/20251020115936 new file mode 100644 index 00000000000000..dc6307c1b6c12d --- /dev/null +++ b/db/schema_migrations/20251020115936 @@ -0,0 +1 @@ +11efcd6b0cfdf71496f36e29f3756edf2b9db84c5c1114ac3fb9984bdb14fffa \ No newline at end of file diff --git a/db/schema_migrations/20251020115938 b/db/schema_migrations/20251020115938 new file mode 100644 index 00000000000000..de29cbb488afd9 --- /dev/null +++ b/db/schema_migrations/20251020115938 @@ -0,0 +1 @@ +8ab8f2b5c1c8af9289083f875316cdbf0f7da9ebb34691746c49c0deeb587131 \ No newline at end of file diff --git a/db/schema_migrations/20251020115941 b/db/schema_migrations/20251020115941 new file mode 100644 index 00000000000000..783b35621664f1 --- /dev/null +++ b/db/schema_migrations/20251020115941 @@ -0,0 +1 @@ +4088c0796d242c92134f5d8600d854d8f1936bad8d0172bd34dec4a83e04f497 \ No newline at end of file diff --git a/db/schema_migrations/20251020115945 b/db/schema_migrations/20251020115945 new file mode 100644 index 00000000000000..540ed909cb55b4 --- /dev/null +++ b/db/schema_migrations/20251020115945 @@ -0,0 +1 @@ +691bd07fb6454760b61f88919f363c66be85609cbd8da7506e11929fe166f9c9 \ No newline at end of file diff --git a/db/schema_migrations/20251020115950 b/db/schema_migrations/20251020115950 new file mode 100644 index 00000000000000..7ad26b8d616952 --- /dev/null +++ b/db/schema_migrations/20251020115950 @@ -0,0 +1 @@ +8739ad742d8f4417099c94bc5eafca0d0bf6d336d44be69cd60950fd7f5c6f4b \ No newline at end of file diff --git a/spec/migrations/backfill_jira_tracker_data_null_sharding_key_spec.rb b/spec/migrations/backfill_jira_tracker_data_null_sharding_key_spec.rb new file mode 100644 index 00000000000000..717cfddf2ca226 --- /dev/null +++ b/spec/migrations/backfill_jira_tracker_data_null_sharding_key_spec.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillJiraTrackerDataNullShardingKey, feature_category: :integrations do + let(:organizations) { table(:organizations) } + let(:jira_tracker_data) { table(:jira_tracker_data) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:integrations) { table(:integrations) } + + let!(:organization) { organizations.create!(id: 1, name: 'Default', path: 'default') } + let!(:group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + let!(:another_group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + + let!(:project) do + projects.create!( + name: 'baz', + path: 'baz', + organization_id: 1, + namespace_id: group.id, + project_namespace_id: group.id + ) + end + + let!(:group_integration) do + integrations.create!(group_id: group.id, type_new: 'Integrations::Jira') + end + + let!(:another_group_integration) do + integrations.create!(group_id: another_group.id, type_new: 'Integrations::Jira') + end + + let!(:project_integration) do + integrations.create!(project_id: project.id, type_new: 'Integrations::Jira') + end + + let!(:organization_integration) do + integrations.create!(organization_id: organization.id, type_new: 'Integrations::Jira', instance: true) + end + + let(:project_tracker_data_to_backfill) do + jira_tracker_data.create!(integration_id: project_integration.id) + end + + let(:group_tracker_data_to_backfill) do + jira_tracker_data.create!(integration_id: group_integration.id) + end + + let(:organization_tracker_data_to_backfill) do + jira_tracker_data.create!(integration_id: organization_integration.id) + end + + let(:valid_group_tracker_data) do + jira_tracker_data.create!(group_id: another_group.id, integration_id: another_group_integration.id) + end + + before do + ApplicationRecord.connection.execute('ALTER TABLE jira_tracker_data DROP CONSTRAINT IF EXISTS check_eca1fbd6bd;') + end + + after do + ApplicationRecord + .connection + .execute( + 'ALTER TABLE jira_tracker_data ADD CONSTRAINT check_eca1fbd6bd ' \ + 'CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1));' + ) + end + + describe "#up" do + it 'sets sharding key for records that do not have it' do + expect(project_tracker_data_to_backfill.project_id).to be_nil + expect(project_tracker_data_to_backfill.group_id).to be_nil + expect(project_tracker_data_to_backfill.organization_id).to be_nil + + expect(group_tracker_data_to_backfill.project_id).to be_nil + expect(group_tracker_data_to_backfill.group_id).to be_nil + expect(group_tracker_data_to_backfill.organization_id).to be_nil + + expect(organization_tracker_data_to_backfill.project_id).to be_nil + expect(organization_tracker_data_to_backfill.group_id).to be_nil + expect(organization_tracker_data_to_backfill.organization_id).to be_nil + + expect(valid_group_tracker_data.project_id).to be_nil + expect(valid_group_tracker_data.group_id).to eq(another_group.id) + expect(valid_group_tracker_data.organization_id).to be_nil + + migrate! + + expect(project_tracker_data_to_backfill.reload.project_id).to eq(project.id) + expect(project_tracker_data_to_backfill.reload.group_id).to be_nil + expect(project_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(group_tracker_data_to_backfill.reload.project_id).to be_nil + expect(group_tracker_data_to_backfill.reload.group_id).to eq(group.id) + expect(group_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(organization_tracker_data_to_backfill.reload.project_id).to be_nil + expect(organization_tracker_data_to_backfill.reload.group_id).to be_nil + expect(organization_tracker_data_to_backfill.reload.organization_id).to eq(organization.id) + + expect(valid_group_tracker_data.reload.project_id).to be_nil + expect(valid_group_tracker_data.reload.group_id).to eq(another_group.id) + expect(valid_group_tracker_data.reload.organization_id).to be_nil + end + end +end -- GitLab