Closed sjaveed closed 6 years ago
r? @tenderlove
(@rails-bot has picked a reviewer for you, use r? to override)
Hi, and thanks for the suggestion / patch!
The new approach seems to be more logical
I don't disagree...
but feel free to let me know if it doesn't fit with the arel thinking
Yeah, that. :confused:
To me this has a few (IMO show-stopping) issues:
= NULL
is never true -- we give meaning to an otherwise-useless expression, instead of changing the meaning of something that someone might've intended to use with its defined semanticsI'd argue # 1 even if we were designing the library from scratch; # 2 is obviously just a consequence of existing history, but it's still important. # 3 is more debatable, both because it's a general principle, and because it's not something the existing library always sticks to.
@matthewd thank you for your comments! I was concerned about all three of your points before I pushed up this PR but figured it would serve as a provocation if nothing else.
IS TRUE
and IS NOT TRUE
to deliver that functionality. I'd imagine if the database has that inconsistency then we should reflect that.One thing that's interesting is that for an ActiveRecord query like User.where.not(active: false)
the new behavior introduced in this PR can be replicated by User.where(active: true).or(User.where(active: nil))
but or
has been notoriously finicky to use. With this PR, you can get the old (current) behavior using User.where(active: false).where.not(active: nil)
which is a lot more tolerant.
In any case I really appreciate your comments and, if this is a no-go, would love it if you could recommend an alternative approach that adds to Arel instead of changing the Equality/NotEqual functionality for PostgreSQL and MySQL!
Thanks!
@matthewd I've pushed up a new PR that might help alleviate your concerns: #528 - it preserves existing behavior but allows using the new behavior in the specific case where it makes a difference: when IS NOT TRUE or IS NOT FALSE is desired.
I'd love your thoughts on it!
Closing since #528 supersedes this now
This brings comparisons against booleans in sync with comparisons against null values
https://www.postgresql.org/docs/9.3/static/functions-comparison.html
For the reasoning behind this, try the following:
Before this pull request, the Equality and NotEqual nodes generated this SQL with the following results:
SELECT COUNT(*) FROM users WHERE users.active = FALSE
returns 1 record (active == false only)SELECT COUNT(*) FROM users WHERE users.active != FALSE
returns 1 record (active == true only i.e. active != false but only counting not-nullable columns)The new approach seems to be more logical but feel free to let me know if it doesn't fit with the arel thinking:
SELECT COUNT(*) FROM users WHERE users.active IS FALSE
returns 1 record (active == false only)SELECT COUNT(*) FROM users WHERE users.active IS NOT FALSE
returns 2 records (active == true and active == null which seems to be a better version of active != false)