Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idempotency bugs in add_reference_concurrently #56

Merged
merged 2 commits into from
Jun 24, 2024

Conversation

ghiculescu
Copy link
Contributor

@ghiculescu ghiculescu commented Jun 24, 2024

The adding of foreign keys in add_reference_concurrently is not idempotent. Instead of being safely skipped here, an error is raised.

The root cause is the merging in of validate: false here. That gets passed through to the check here. It means that if you use add_reference_concurrently to create a validated foreign key, and then call add_reference_concurrently again, it will always raise, because the matching foreign key won't be found.

I'm not sure what the right approach to fixing this is yet but I wanted to add some failing tests to demonstrate the issue.

@ghiculescu ghiculescu marked this pull request as ready for review June 24, 2024 05:43
assert_empty @connection.foreign_keys(:projects)

migrate AddReferenceForeignKeyNoValidate
assert_raises_with_message(StandardError, /column "user_id" of relation "projects" already exists/) do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is expected behaviour, so I added this as a passing test (though I guess it would be nice if it was consistent with add_reference_concurrently).

@fatkodima fatkodima merged commit e26c156 into fatkodima:master Jun 24, 2024
5 checks passed
@fatkodima
Copy link
Owner

Thank you for the PR!

@ghiculescu ghiculescu deleted the idempotency-bugs branch June 24, 2024 23:08
@ghiculescu
Copy link
Contributor Author

Thanks for the fix!

@ghiculescu
Copy link
Contributor Author

We should have included this test too:

    def test_add_reference_concurrently_with_unvalidated_foreign_key_is_idempotent
      assert_empty connection.foreign_keys(:milestones)

      connection.add_reference_concurrently :milestones, :project, foreign_key: { validate: false }
      connection.add_reference_concurrently :milestones, :project, foreign_key: { validate: false }

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

It passes with this fix, so all good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants