99 lines
3.2 KiB
Ruby
99 lines
3.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module BackgroundMigration
|
|
# Class that fixes the incorrectly set authored_date within
|
|
# issue_metrics table
|
|
class FixFirstMentionedInCommitAt
|
|
SUB_BATCH_SIZE = 500
|
|
|
|
# rubocop: disable Style/Documentation
|
|
class TmpIssueMetrics < ActiveRecord::Base
|
|
include EachBatch
|
|
|
|
self.table_name = 'issue_metrics'
|
|
|
|
def self.from_2020
|
|
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
|
|
# rubocop: enable Style/Documentation
|
|
|
|
def perform(start_id, end_id)
|
|
scope(start_id, end_id).each_batch(of: SUB_BATCH_SIZE, column: :issue_id) do |sub_batch|
|
|
first, last = sub_batch.pick(Arel.sql('min(issue_id), max(issue_id)'))
|
|
|
|
# The query need to be reconstructed because .each_batch modifies the default scope
|
|
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/330510
|
|
inner_query = TmpIssueMetrics
|
|
.unscoped
|
|
.merge(scope(first, last))
|
|
.from("issue_metrics, #{lateral_query}")
|
|
.select('issue_metrics.issue_id', 'first_authored_date.authored_date')
|
|
.where('issue_metrics.first_mentioned_in_commit_at > first_authored_date.authored_date')
|
|
|
|
TmpIssueMetrics.connection.execute <<~UPDATE_METRICS
|
|
WITH cte AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
|
|
#{inner_query.to_sql}
|
|
)
|
|
UPDATE issue_metrics
|
|
SET
|
|
first_mentioned_in_commit_at = cte.authored_date
|
|
FROM
|
|
cte
|
|
WHERE
|
|
cte.issue_id = issue_metrics.issue_id
|
|
UPDATE_METRICS
|
|
end
|
|
|
|
mark_job_as_succeeded(start_id, end_id)
|
|
end
|
|
|
|
private
|
|
|
|
def mark_job_as_succeeded(*arguments)
|
|
Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
|
|
'FixFirstMentionedInCommitAt',
|
|
arguments
|
|
)
|
|
end
|
|
|
|
def scope(start_id, end_id)
|
|
TmpIssueMetrics.from_2020.where(issue_id: start_id..end_id)
|
|
end
|
|
|
|
def lateral_query
|
|
<<~SQL
|
|
LATERAL (
|
|
SELECT MIN(first_authored_date.authored_date) as authored_date
|
|
FROM merge_requests_closing_issues,
|
|
LATERAL (
|
|
SELECT id
|
|
FROM merge_request_diffs
|
|
WHERE merge_request_id = merge_requests_closing_issues.merge_request_id
|
|
ORDER BY id DESC
|
|
LIMIT 1
|
|
) last_diff_id,
|
|
LATERAL (
|
|
SELECT authored_date
|
|
FROM merge_request_diff_commits
|
|
WHERE
|
|
merge_request_diff_id = last_diff_id.id
|
|
ORDER BY relative_order DESC
|
|
LIMIT 1
|
|
) first_authored_date
|
|
WHERE merge_requests_closing_issues.issue_id = issue_metrics.issue_id
|
|
) first_authored_date
|
|
SQL
|
|
end
|
|
end
|
|
end
|
|
end
|