diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-06 06:10:25 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-06 06:10:25 +0300 |
commit | 806b829e76120085d80759dabc110f0328cfb7ac (patch) | |
tree | f8fff9251baabf1974cf879c456903ba8fe5059d /app/models/merge_request_diff.rb | |
parent | bfb0d93c767b4df4ab31a836d40cd7a1657916b5 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/merge_request_diff.rb')
-rw-r--r-- | app/models/merge_request_diff.rb | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index a9b708179a7..25ee3fb7e83 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -113,14 +113,29 @@ class MergeRequestDiff < ApplicationRecord joins(merge_request: :metrics).where(condition) end + # This scope uses LATERAL JOIN to find the most recent MR diff association for the given merge requests. + # To avoid joining the merge_requests table, we build an in memory table using the merge request ids. + # Example: + # SELECT ... + # FROM (VALUES (MR_ID_1),(MR_ID_2)) merge_requests (id) + # INNER JOIN LATERAL (...) scope :latest_diff_for_merge_requests, -> (merge_requests) do - inner_select = MergeRequestDiff - .default_scoped - .distinct - .select("FIRST_VALUE(id) OVER (PARTITION BY merge_request_id ORDER BY created_at DESC) as id") - .where(merge_request: merge_requests) + mrs = Array(merge_requests) + return MergeRequestDiff.none if mrs.empty? - joins("INNER JOIN (#{inner_select.to_sql}) latest_diffs ON latest_diffs.id = merge_request_diffs.id") + merge_request_table = MergeRequest.arel_table + merge_request_diff_table = MergeRequestDiff.arel_table + + join_query = MergeRequestDiff + .where(merge_request_table[:id].eq(merge_request_diff_table[:merge_request_id])) + .order(created_at: :desc) + .limit(1) + + mr_id_list = mrs.map { |mr| "(#{Integer(mr.id)})" }.join(",") + + MergeRequestDiff + .from("(VALUES #{mr_id_list}) merge_requests (id)") + .joins("INNER JOIN LATERAL (#{join_query.to_sql}) #{MergeRequestDiff.table_name} ON TRUE") .includes(:merge_request_diff_commits) end |