Commit 40a0bf58 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'rename_column_concurrently_specify_batch_col_name' into 'master'

Add batch_column_name option to rename_column_concurrently

See merge request gitlab-org/gitlab!30106
parents 80150267 9c62749d
...@@ -378,7 +378,7 @@ module Gitlab ...@@ -378,7 +378,7 @@ module Gitlab
# make things _more_ complex). # make things _more_ complex).
# #
# `batch_column_name` option is for tables without primary key, in this # `batch_column_name` option is for tables without primary key, in this
# case an other unique integer column can be used. Example: :user_id # case another unique integer column can be used. Example: :user_id
# #
# rubocop: disable Metrics/AbcSize # rubocop: disable Metrics/AbcSize
def update_column_in_batches(table, column, value, batch_size: nil, batch_column_name: :id) def update_column_in_batches(table, column, value, batch_size: nil, batch_column_name: :id)
...@@ -519,14 +519,20 @@ module Gitlab ...@@ -519,14 +519,20 @@ module Gitlab
# new - The new column name. # new - The new column name.
# type - The type of the new column. If no type is given the old column's # type - The type of the new column. If no type is given the old column's
# type is used. # type is used.
def rename_column_concurrently(table, old, new, type: nil) # batch_column_name - option is for tables without primary key, in this
# case another unique integer column can be used. Example: :user_id
def rename_column_concurrently(table, old, new, type: nil, batch_column_name: :id)
unless column_exists?(table, batch_column_name)
raise "Column #{batch_column_name} does not exist on #{table}"
end
if transaction_open? if transaction_open?
raise 'rename_column_concurrently can not be run inside a transaction' raise 'rename_column_concurrently can not be run inside a transaction'
end end
check_trigger_permissions!(table) check_trigger_permissions!(table)
create_column_from(table, old, new, type: type) create_column_from(table, old, new, type: type, batch_column_name: batch_column_name)
install_rename_triggers(table, old, new) install_rename_triggers(table, old, new)
end end
...@@ -626,14 +632,20 @@ module Gitlab ...@@ -626,14 +632,20 @@ module Gitlab
# new - The new column name. # new - The new column name.
# type - The type of the old column. If no type is given the new column's # type - The type of the old column. If no type is given the new column's
# type is used. # type is used.
def undo_cleanup_concurrent_column_rename(table, old, new, type: nil) # batch_column_name - option is for tables without primary key, in this
# case another unique integer column can be used. Example: :user_id
def undo_cleanup_concurrent_column_rename(table, old, new, type: nil, batch_column_name: :id)
unless column_exists?(table, batch_column_name)
raise "Column #{batch_column_name} does not exist on #{table}"
end
if transaction_open? if transaction_open?
raise 'undo_cleanup_concurrent_column_rename can not be run inside a transaction' raise 'undo_cleanup_concurrent_column_rename can not be run inside a transaction'
end end
check_trigger_permissions!(table) check_trigger_permissions!(table)
create_column_from(table, new, old, type: type) create_column_from(table, new, old, type: type, batch_column_name: batch_column_name)
install_rename_triggers(table, old, new) install_rename_triggers(table, old, new)
end end
...@@ -1355,7 +1367,7 @@ into similar problems in the future (e.g. when new tables are created). ...@@ -1355,7 +1367,7 @@ into similar problems in the future (e.g. when new tables are created).
"ON DELETE #{on_delete.upcase}" "ON DELETE #{on_delete.upcase}"
end end
def create_column_from(table, old, new, type: nil) def create_column_from(table, old, new, type: nil, batch_column_name: :id)
old_col = column_for(table, old) old_col = column_for(table, old)
new_type = type || old_col.type new_type = type || old_col.type
...@@ -1369,7 +1381,7 @@ into similar problems in the future (e.g. when new tables are created). ...@@ -1369,7 +1381,7 @@ into similar problems in the future (e.g. when new tables are created).
# necessary since we copy over old values further down. # necessary since we copy over old values further down.
change_column_default(table, new, old_col.default) unless old_col.default.nil? change_column_default(table, new, old_col.default) unless old_col.default.nil?
update_column_in_batches(table, new, Arel::Table.new(table)[old]) update_column_in_batches(table, new, Arel::Table.new(table)[old], batch_column_name: batch_column_name)
change_column_null(table, new, false) unless old_col.null change_column_null(table, new, false) unless old_col.null
......
...@@ -790,6 +790,25 @@ describe Gitlab::Database::MigrationHelpers do ...@@ -790,6 +790,25 @@ describe Gitlab::Database::MigrationHelpers do
model.rename_column_concurrently(:users, :old, :new) model.rename_column_concurrently(:users, :old, :new)
end end
it 'passes the batch_column_name' do
expect(model).to receive(:column_exists?).with(:users, :other_batch_column).and_return(true)
expect(model).to receive(:check_trigger_permissions!).and_return(true)
expect(model).to receive(:create_column_from).with(
:users, :old, :new, type: nil, batch_column_name: :other_batch_column
).and_return(true)
expect(model).to receive(:install_rename_triggers).and_return(true)
model.rename_column_concurrently(:users, :old, :new, batch_column_name: :other_batch_column)
end
it 'raises an error with invalid batch_column_name' do
expect do
model.rename_column_concurrently(:users, :old, :new, batch_column_name: :invalid)
end.to raise_error(RuntimeError, /Column invalid does not exist on users/)
end
context 'when default is false' do context 'when default is false' do
let(:old_column) do let(:old_column) do
double(:column, double(:column,
...@@ -904,6 +923,25 @@ describe Gitlab::Database::MigrationHelpers do ...@@ -904,6 +923,25 @@ describe Gitlab::Database::MigrationHelpers do
model.undo_cleanup_concurrent_column_rename(:users, :old, :new) model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
end end
it 'passes the batch_column_name' do
expect(model).to receive(:column_exists?).with(:users, :other_batch_column).and_return(true)
expect(model).to receive(:check_trigger_permissions!).and_return(true)
expect(model).to receive(:create_column_from).with(
:users, :new, :old, type: nil, batch_column_name: :other_batch_column
).and_return(true)
expect(model).to receive(:install_rename_triggers).and_return(true)
model.undo_cleanup_concurrent_column_rename(:users, :old, :new, batch_column_name: :other_batch_column)
end
it 'raises an error with invalid batch_column_name' do
expect do
model.undo_cleanup_concurrent_column_rename(:users, :old, :new, batch_column_name: :invalid)
end.to raise_error(RuntimeError, /Column invalid does not exist on users/)
end
context 'when default is false' do context 'when default is false' do
let(:new_column) do let(:new_column) do
double(:column, double(:column,
......
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