Commit e30842f1 authored by Yannis Roussos's avatar Yannis Roussos

Merge branch '343694-fix-issue-metrics-index-creation-error' into 'master'

Fix issue_metrics index creation error

See merge request gitlab-org/gitlab!72928
parents 50e1ace0 22366a0c
...@@ -6,7 +6,9 @@ class AddTemporaryIndexToIssueMetrics < Gitlab::Database::Migration[1.0] ...@@ -6,7 +6,9 @@ class AddTemporaryIndexToIssueMetrics < Gitlab::Database::Migration[1.0]
INDEX_NAME = 'index_issue_metrics_first_mentioned_in_commit' INDEX_NAME = 'index_issue_metrics_first_mentioned_in_commit'
def up def up
add_concurrent_index :issue_metrics, :issue_id, where: 'EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019', name: INDEX_NAME condition = Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics
.first_mentioned_in_commit_at_condition
add_concurrent_index :issue_metrics, :issue_id, where: condition, name: INDEX_NAME
end end
def down def down
......
...@@ -8,8 +8,8 @@ class ScheduleFixFirstMentionedInCommitAtJob < Gitlab::Database::Migration[1.0] ...@@ -8,8 +8,8 @@ class ScheduleFixFirstMentionedInCommitAtJob < Gitlab::Database::Migration[1.0]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
scope = define_batchable_model('issue_metrics') scope = Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics
.where('EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019') .from_2020
queue_background_migration_jobs_by_range_at_intervals( queue_background_migration_jobs_by_range_at_intervals(
scope, scope,
......
...@@ -14,7 +14,15 @@ module Gitlab ...@@ -14,7 +14,15 @@ module Gitlab
self.table_name = 'issue_metrics' self.table_name = 'issue_metrics'
def self.from_2020 def self.from_2020
where('EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019') where(first_mentioned_in_commit_at_condition)
end
def self.first_mentioned_in_commit_at_condition
if columns_hash['first_mentioned_in_commit_at'].sql_type == 'timestamp without time zone'
'EXTRACT(YEAR FROM first_mentioned_in_commit_at) > 2019'
else
"EXTRACT(YEAR FROM first_mentioned_in_commit_at at time zone 'UTC') > 2019"
end
end end
end end
# rubocop: enable Style/Documentation # rubocop: enable Style/Documentation
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20211004110500_add_temporary_index_to_issue_metrics.rb')
RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migration, schema: 20211004110500 do RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migration, schema: 20211004110500 do
let(:namespaces) { table(:namespaces) } let(:namespaces) { table(:namespaces) }
...@@ -99,42 +100,67 @@ RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migrat ...@@ -99,42 +100,67 @@ RSpec.describe Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt, :migrat
.perform(issue_metrics.minimum(:issue_id), issue_metrics.maximum(:issue_id)) .perform(issue_metrics.minimum(:issue_id), issue_metrics.maximum(:issue_id))
end end
it "marks successful slices as completed" do shared_examples 'fixes first_mentioned_in_commit_at' do
min_issue_id = issue_metrics.minimum(:issue_id) it "marks successful slices as completed" do
max_issue_id = issue_metrics.maximum(:issue_id) min_issue_id = issue_metrics.minimum(:issue_id)
max_issue_id = issue_metrics.maximum(:issue_id)
expect(subject).to receive(:mark_job_as_succeeded).with(min_issue_id, max_issue_id) expect(subject).to receive(:mark_job_as_succeeded).with(min_issue_id, max_issue_id)
subject.perform(min_issue_id, max_issue_id) subject.perform(min_issue_id, max_issue_id)
end end
context 'when the persisted first_mentioned_in_commit_at is later than the first commit authored_date' do context 'when the persisted first_mentioned_in_commit_at is later than the first commit authored_date' do
it 'updates the issue_metrics record' do it 'updates the issue_metrics record' do
record1 = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: Time.current) record1 = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: Time.current)
record2 = issue_metrics.create!(issue_id: issue2.id, first_mentioned_in_commit_at: Time.current) record2 = issue_metrics.create!(issue_id: issue2.id, first_mentioned_in_commit_at: Time.current)
run_migration run_migration
record1.reload record1.reload
record2.reload record2.reload
expect(record1.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit2.authored_date) expect(record1.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit2.authored_date)
expect(record2.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit3.authored_date) expect(record2.first_mentioned_in_commit_at).to be_within(2.seconds).of(commit3.authored_date)
end
end
context 'when the persisted first_mentioned_in_commit_at is earlier than the first commit authored_date' do
it 'does not update the issue_metrics record' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: 20.days.ago)
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
end
end end
end
context 'when the persisted first_mentioned_in_commit_at is earlier than the first commit authored_date' do context 'when the first_mentioned_in_commit_at is null' do
it 'does not update the issue_metrics record' do it 'does nothing' do
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: 20.days.ago) record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: nil)
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at } expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at }
end
end end
end end
context 'when the first_mentioned_in_commit_at is null' do describe 'running the migration when first_mentioned_in_commit_at is timestamp without time zone' do
it 'does nothing' do it_behaves_like 'fixes first_mentioned_in_commit_at'
record = issue_metrics.create!(issue_id: issue1.id, first_mentioned_in_commit_at: nil) end
describe 'running the migration when first_mentioned_in_commit_at is timestamp with time zone' do
around do |example|
AddTemporaryIndexToIssueMetrics.new.down
ActiveRecord::Base.connection.execute "ALTER TABLE issue_metrics ALTER first_mentioned_in_commit_at type timestamp with time zone"
Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics.reset_column_information
AddTemporaryIndexToIssueMetrics.new.up
expect { run_migration }.not_to change { record.reload.first_mentioned_in_commit_at } example.run
AddTemporaryIndexToIssueMetrics.new.down
ActiveRecord::Base.connection.execute "ALTER TABLE issue_metrics ALTER first_mentioned_in_commit_at type timestamp without time zone"
Gitlab::BackgroundMigration::FixFirstMentionedInCommitAt::TmpIssueMetrics.reset_column_information
AddTemporaryIndexToIssueMetrics.new.up
end end
it_behaves_like 'fixes first_mentioned_in_commit_at'
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment