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

Ignore invalid PRIMARY KEY values in ActiveRecord::Persistence.delete method #49738

Merged
merged 1 commit into from
Oct 23, 2023

Conversation

fatkodima
Copy link
Member

When some invalid primary key values are passed to ActiveRecord::Persistence.delete method, ActiveRecord still perform a DELETE query even if it is not needed. For example,

irb(main):001> User.delete([])
  User Delete All (0.6ms)  DELETE FROM "users" WHERE 1=0
=> 0

So people usually add conditions around the call like User.delete(ids) if ids.compact.any? or User.delete(id) if id or just forget these conditions and unneeded queries are ran. But we can remove this burden from the user. Recent real-world example https://github.com/rails/solid_cache/blob/9be6755a2d8c8fd1c294912e1fbf6bbb69410c61/app/models/solid_cache/entry.rb#L64-L66

But, can NULL be a valid value and can we actually ignore it? I checked, and it turns out that primary keys cannot be NULL - ANSI standard says so, PostgreSQL, MySQL, SQL Server and Oracle Server conform to that. There is an exception from SQLite. In the docs it says that it allows NULLs due to some historical reasons, unless some conditions are met (one of them is explicit NOT NULL or table is created in STRICT mode, read the docs from the link for the details). But in rails, we explicitly set it NOT NULL

primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
and have a strict mode (#45346). So, I think it is safe to ignore nils as values provided to #delete.

Copy link
Contributor

@nvasilevski nvasilevski left a comment

Choose a reason for hiding this comment

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

I guess if someone has strong concerns about nil or an array of [nil] should be supported as a valid primary key value we could drop the compact and only focus on an empty array [] case because this seems to be an extremely common pattern Rails can handle internally

Copy link
Member

@byroot byroot left a comment

Choose a reason for hiding this comment

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

Just a minor thing, otherwise 👍

when nil
0
when Array
ids = id_or_array.compact
Copy link
Member

Choose a reason for hiding this comment

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

I think the compact is a bit much. I'm fine with just checking nil and empty arrays though, as I see how we can end up here on the happy path.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, makes sense! Changed that.

@fatkodima fatkodima force-pushed the avoid-unneeded-queries-in-delete branch from 8eb303e to 39781d2 Compare October 23, 2023 18:10
@byroot byroot merged commit 55bf2df into rails:main Oct 23, 2023
3 of 4 checks passed
@byroot
Copy link
Member

byroot commented Oct 23, 2023

Thanks!

@fatkodima fatkodima deleted the avoid-unneeded-queries-in-delete branch October 23, 2023 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants