Commit e97671b8 authored by Stan Hu's avatar Stan Hu

Simplify implementation and allow for batch updates in MySQL

parent dfdf22c7
...@@ -15,18 +15,26 @@ class IssuesMovedToIdForeignKey < ActiveRecord::Migration ...@@ -15,18 +15,26 @@ class IssuesMovedToIdForeignKey < ActiveRecord::Migration
self.table_name = 'issues' self.table_name = 'issues'
def self.with_orphaned_moved_to_issues def self.with_orphaned_moved_to_issues
# Be careful to use a second table here for comparison otherwise we'll null if Gitlab::Database.postgresql?
# out all rows that don't have id == moved_to_id! # Be careful to use a second table here for comparison otherwise we'll null
where('NOT EXISTS (SELECT true FROM issues b WHERE issues.moved_to_id = b.id)') # out all rows that don't have id == moved.to_id!
.where('moved_to_id IS NOT NULL') where('NOT EXISTS (SELECT true FROM issues B WHERE issues.moved_to_id = B.id)')
.where('moved_to_id IS NOT NULL')
else
# MySQL doesn't allow modification of the same table in a subquery,
# and using a temporary table isn't automatically guaranteed to work
# due to the MySQL query optimizer. See
# https://dev.mysql.com/doc/refman/5.7/en/update.html for more
# details.
joins('LEFT JOIN issues AS b ON issues.moved_to_id = b.id')
.where('issues.moved_to_id IS NOT NULL AND b.id IS NULL')
end
end end
end end
def up def up
if Gitlab::Database.postgresql? Issue.with_orphaned_moved_to_issues.each_batch(of: 100) do |batch|
postgresql_remove_orphaned_moved_to_ids batch.update_all(moved_to_id: nil)
else
mysql_remove_orphaned_moved_to_ids
end end
add_concurrent_foreign_key( add_concurrent_foreign_key(
...@@ -45,23 +53,4 @@ class IssuesMovedToIdForeignKey < ActiveRecord::Migration ...@@ -45,23 +53,4 @@ class IssuesMovedToIdForeignKey < ActiveRecord::Migration
remove_foreign_key_without_error(:issues, column: :moved_to_id) remove_foreign_key_without_error(:issues, column: :moved_to_id)
remove_concurrent_index(:issues, :moved_to_id) remove_concurrent_index(:issues, :moved_to_id)
end end
private
def postgresql_remove_orphaned_moved_to_ids
Issue.with_orphaned_moved_to_issues.each_batch(of: 100) do |batch|
batch.update_all(moved_to_id: nil)
end
end
# MySQL doesn't allow modification of the same table in a subquery. See
# https://dev.mysql.com/doc/refman/5.7/en/update.html for more details.
def mysql_remove_orphaned_moved_to_ids
execute <<~SQL
UPDATE issues AS a
LEFT JOIN issues AS b ON a.moved_to_id = b.id
SET a.moved_to_id = NULL
WHERE a.moved_to_id IS NOT NULL AND b.id IS NULL;
SQL
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