diff options
Diffstat (limited to 'lib/gitlab/background_migration/replace_blocked_by_links.rb')
-rw-r--r-- | lib/gitlab/background_migration/replace_blocked_by_links.rb | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/gitlab/background_migration/replace_blocked_by_links.rb b/lib/gitlab/background_migration/replace_blocked_by_links.rb index 26626aaef79..0c29887bb00 100644 --- a/lib/gitlab/background_migration/replace_blocked_by_links.rb +++ b/lib/gitlab/background_migration/replace_blocked_by_links.rb @@ -12,14 +12,19 @@ module Gitlab blocked_by_links = IssueLink.where(id: start_id..stop_id).where(link_type: 2) ActiveRecord::Base.transaction do - # if there is duplicit bi-directional relation (issue2 is blocked by issue1 - # and issue1 already links issue2), then we can just delete 'blocked by'. - # This should be rare as we have a pre-create check which checks if issues are - # already linked - blocked_by_links + # There could be two edge cases: + # 1) issue1 is blocked by issue2 AND issue2 blocks issue1 (type 1) + # 2) issue1 is blocked by issue2 AND issue2 is related to issue1 (type 0) + # In both cases cases we couldn't convert blocked by relation to + # `issue2 blocks issue` because there is already a link with the same + # source/target id. To avoid these conflicts, we first delete any + # "opposite" links before we update `blocked by` relation. This + # should be rare as we have a pre-create check which checks if issues + # are already linked + opposite_ids = blocked_by_links + .select('opposite_links.id') .joins('INNER JOIN issue_links as opposite_links ON issue_links.source_id = opposite_links.target_id AND issue_links.target_id = opposite_links.source_id') - .where('opposite_links.link_type': 1) - .delete_all + IssueLink.where(id: opposite_ids).delete_all blocked_by_links.update_all('source_id=target_id,target_id=source_id,link_type=1') end |