-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Add explain
support for methods like last
, pluck
and count
#50482
Conversation
2dfe3fe
to
b1d969f
Compare
explain
support for calculation methods like count
explain
support for methods like last
, pluck
and count
b18258e
to
c291af7
Compare
@@ -3,6 +3,37 @@ | |||
module ActiveRecord | |||
# = Active Record \Relation | |||
class Relation | |||
class ExplainProxy # :nodoc: | |||
SUPPORTED_METHODS = [:count, :first, :last, :maximum, :minimum, :pluck, :sum] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we only support those methods why use method missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the implementation to use regular methods. This also makes sure the method signatures match.
0f43745
to
205c426
Compare
`explain` can be called on a relation to explain how the database would execute a query. Currently `explain` doesn't work for queries using `last`, `pluck` or `count`, as these return the actual result instead of a relation. This makes it difficult to optimize these queries. By letting `explain` return a proxy instead, we can support these methods. ```ruby User.all.explain.count \# => "EXPLAIN SELECT COUNT(*) FROM `users`" User.all.explain.maximum(:id) \# => "EXPLAIN SELECT MAX(`users`.`id`) FROM `users`" ``` This breaks the existing behaviour in that it requires calling inspect after explain. ```ruby User.all.explain.inspect \# => "EXPLAIN SELECT `users`.* FROM `users`" ``` However, as `explain` is mostly used from the commandline, this won't be a problem as inspect is called automatically in IRB. Co-authored-by: Rafael Mendonça França <rafael@rubyonrails.org>
205c426
to
1f83af3
Compare
Is the first line in the CHANGELOG complete? |
@fxn Would you want to see all methods? |
@p8 The current sentence is
As a reader, I'd interpret the support is for exactly those three. Instead of "like", I believe it would be more informative to list them all. You read the CHANGELOG, and you know what is new without having to think more. See what I mean? |
Follow-up to #50482. RDoc does not support backticks the way that Markdown does. Instead, inline code must be wrapped with `+` or `<tt>`.
Motivation / Background
explain
can be called on a relation to explain how the database would execute a query.Currently
explain
doesn't work for queries usinglast
,pluck
orcount
, as these return the actual result instead of a relation. This makes it difficult to optimize these queries.By letting
explain
return a proxy instead, we can support these methods.Detail
This breaks the existing behaviour in that it requires calling inspect after explain.
However, as
explain
is mostly used from the commandline, this won't be a problem as inspect is called automatically in IRB.Additional information
This is a variation of #50424 which used arguments instead of a proxy and method calls.
Another variation could be passing a block instead. This would not break the current behaviour, but it's a bit more verbose:
With a symbol-to-proc it becomes a bit terser:
Unlike the proxy solution, this notation could also be applied to
to_sql
:Or we could use method name variations, but that would break with the arguments that can be passed to
explain
, likeexplain(:analyze, :buffers)
:Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]