Commit 8e46980d authored by pbair's avatar pbair

Fix duplicates in create_table_with_constraints

Fix the `create_table_with_constraints` helper from attempting to add
duplicate constraints when the `with_lock_retries` helper retries the
create table logic.
parent 0c4ed5e9
...@@ -87,9 +87,10 @@ module Gitlab ...@@ -87,9 +87,10 @@ module Gitlab
# See Rails' `create_table` for more info on the available arguments. # See Rails' `create_table` for more info on the available arguments.
def create_table_with_constraints(table_name, **options, &block) def create_table_with_constraints(table_name, **options, &block)
helper_context = self helper_context = self
check_constraints = []
with_lock_retries do with_lock_retries do
check_constraints = []
create_table(table_name, **options) do |t| create_table(table_name, **options) do |t|
t.define_singleton_method(:check_constraint) do |name, definition| t.define_singleton_method(:check_constraint) do |name, definition|
helper_context.send(:validate_check_constraint_name!, name) # rubocop:disable GitlabSecurity/PublicSend helper_context.send(:validate_check_constraint_name!, name) # rubocop:disable GitlabSecurity/PublicSend
......
...@@ -180,6 +180,32 @@ RSpec.describe Gitlab::Database::MigrationHelpers do ...@@ -180,6 +180,32 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end end
end end
context 'when with_lock_retries re-runs the block' do
it 'only creates constraint for unique definitions' do
expected_sql = <<~SQL
ALTER TABLE "#{table_name}"\nADD CONSTRAINT "check_cda6f69506" CHECK (char_length("name") <= 255)
SQL
expect(model).to receive(:create_table).twice.and_call_original
expect(model).to receive(:execute).with(expected_sql).and_raise(ActiveRecord::LockWaitTimeout)
expect(model).to receive(:execute).with(expected_sql).and_call_original
model.create_table_with_constraints table_name do |t|
t.timestamps_with_timezone
t.integer :some_id, null: false
t.boolean :active, null: false, default: true
t.text :name
t.text_limit :name, 255
end
expect_table_columns_to_match(column_attributes, table_name)
expect_check_constraint(table_name, 'check_cda6f69506', 'char_length(name) <= 255')
end
end
context 'when constraints are given invalid names' do context 'when constraints are given invalid names' do
let(:expected_max_length) { described_class::MAX_IDENTIFIER_NAME_LENGTH } let(:expected_max_length) { described_class::MAX_IDENTIFIER_NAME_LENGTH }
let(:expected_error_message) { "The maximum allowed constraint name is #{expected_max_length} characters" } let(:expected_error_message) { "The maximum allowed constraint name is #{expected_max_length} characters" }
......
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