Skip to content

Commit

Permalink
Idempotency bugs in add_reference_concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiculescu committed Jun 24, 2024
1 parent db786ee commit 03da3de
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
24 changes: 24 additions & 0 deletions test/command_checker/add_reference_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,30 @@ def test_add_reference_foreign_key_no_validate
assert_safe AddReferenceForeignKeyNoValidate
end

def test_add_reference_foreign_key_no_validate_is_not_idempotent
assert_empty @connection.foreign_keys(:projects)

migrate AddReferenceForeignKeyNoValidate
assert_raises_with_message(StandardError, /column "user_id" of relation "projects" already exists/) do
migrate AddReferenceForeignKeyNoValidate
end
ensure
migrate AddReferenceForeignKeyNoValidate, direction: :down
assert_empty @connection.foreign_keys(:projects)
end

class AddReferenceForeignKeyNoValidatePluralizeName < TestMigration
disable_ddl_transaction!

def change
add_reference :projects, :users, index: false, foreign_key: { validate: false }
end
end

def test_add_reference_foreign_key_no_validate_with_pluralized_table_name
assert_safe AddReferenceForeignKeyNoValidatePluralizeName
end

class AddReferenceForeignKeyValidate < TestMigration
def change
add_reference :projects, :user, index: false, foreign_key: { validate: true }
Expand Down
25 changes: 25 additions & 0 deletions test/command_checker/foreign_keys_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,31 @@ def test_add_foreign_key_no_validate
assert_safe AddForeignKeyNoValidate
end

def test_add_foreign_key_no_validate_is_idempotent
assert_empty @connection.foreign_keys(:projects)

migrate AddForeignKeyNoValidate
migrate AddForeignKeyNoValidate
migrate AddForeignKeyNoValidate

assert_equal 1, @connection.foreign_keys(:projects).size
ensure
migrate AddForeignKeyNoValidate, direction: :down
assert_empty @connection.foreign_keys(:projects)
end

class AddForeignKeySingularToTable < TestMigration
def change
add_foreign_key :projects, :user, validate: false
end
end

def test_add_foreign_key_no_validate
assert_raises_with_message(StandardError, /PG::UndefinedTable: ERROR: relation "user" does not exist/i) do
assert_safe AddForeignKeySingularToTable
end
end

class AddForeignKeyFromNewTable < TestMigration
def change
create_table :posts_new do |t|
Expand Down
29 changes: 29 additions & 0 deletions test/schema_statements/add_reference_concurrently_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,35 @@ def test_add_reference_concurrently_with_foreign_key
end
end

def test_add_reference_concurrently_with_foreign_key_is_idempotent
assert_empty connection.foreign_keys(:milestones)

connection.add_reference_concurrently :milestones, :project, foreign_key: true
connection.add_reference_concurrently :milestones, :project, foreign_key: true
connection.add_reference_concurrently :milestones, :project, foreign_key: true

assert_equal 1, connection.foreign_keys(:milestones).size
end

def test_add_reference_concurrently_with_foreign_key_with_pluralized_table_name
assert_sql(
'REFERENCES "projects" ("id") NOT VALID',
'ALTER TABLE "milestones" VALIDATE CONSTRAINT'
) do
connection.add_reference_concurrently :milestones, :projects, foreign_key: true
end
end

def test_add_reference_concurrently_with_foreign_key_is_idempotent_with_pluralized_table_name
assert_empty connection.foreign_keys(:milestones)

connection.add_reference_concurrently :milestones, :projects, foreign_key: true
connection.add_reference_concurrently :milestones, :projects, foreign_key: true
connection.add_reference_concurrently :milestones, :projects, foreign_key: true

assert_equal 1, connection.foreign_keys(:milestones).size
end

def test_add_reference_concurrently_with_unvalidated_foreign_key
refute_sql("VALIDATE CONSTRAINT") do
connection.add_reference_concurrently :milestones, :project, foreign_key: { validate: false }
Expand Down

0 comments on commit 03da3de

Please sign in to comment.