Currently views only implements group_by_numeric handlers and any time a group by function is used it forces the group_by_numeric handler regardless of what the original handler was. If you look at the code currently in handlers/views_handler_field_group_by_numeric.inc you will notice that it is complete general and not specific to numeric in any way. It appears the other group_by_numeric handlers are the same way.
I propose that the generic code by moved into the base handlers and the group by functions leave the default handler alone. Making that change in itself actually provides more functionality then is currently provided since you can use any handler with group by functions instead of just numeric.
The next step is to make the group by handler overrides customizable so people can force a different handler if they have need to. I went ahead and made the changes necessary for handler_field, but I'd like to get agreement before going ahead with other group_by handlers.
Please note that the net is: removal of code, more features, and no downside.
The cases where the default handler won't work were not allowed in the previous case since it forced the numeric handler regardless of default handler. So a follow-up issue would be to solve that problem by making the group_by handlers customization exposed (as there is a @TODO in the code for).
Also note that the current design (once the the group by handler customizations are exposed) will force people to write two handlers (one for regular and one for group by) regardless of whether or not they really need to and will end up just copy and pasting group_by_numeric.
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | 1073350-group-by-aggregation-and-field-api.patch | 14.46 KB | merlinofchaos |
| #9 | 1073350-group-by.patch | 5.83 KB | boombatower |
| #1 | 1073350-group-by.patch | 5.45 KB | boombatower |
Comments
Comment #1
boombatower commentedOr you can pull from https://github.com/boombatower/views/tree/7.x-3.x-groupby.
Edit, forgot to include on patch so one can see:
Comment #2
boombatower commentedI see to get
with the combination of #1073378: Add time interval handler.
Why would $this->query not be set?
Comment #3
merlinofchaos commentedUnfortunately this patch basically reverts to earlier behavior, where some massive majority of handlers (particularly entity handlers, for example) will basically destroy the "group by" by adding additional fields. That is not acceptable, particularly after I told you twice that this is a problem when we discussed this.
In views_plugin_display::get_handlers() there is this if:
That's what sets the override handlers. We can add something like this code:
Then, you can specify what group by handler to use. It can be the same or different, as long as your handler properly handles all of the aggregation stuff. This is going to be necessary to fix the group by stuff for field api anyhow.
Comment #4
boombatower commentedWe can solve this however everybody likes, but I said as much in the initial post. Yes, there needs to be a way to override and that this code doesn't add it.
Something that I tried to point out multiple times and explained in initial post is that it makes little sense to defaultly force everyone to define an additional class. Yes, I understand that "many" (I still believe most won't since I can envision countless format handlers that have nothing to do with extra fields) will need an additional class, but regardless we already know that not all of them will. So we have two approaches, force 100% to define extra class (or explicitly list themselves as the group by handler [#3]) or default to assuming the same handler thus allowing < 100% to need to deal with either method.
To summarize 100% have to include extra code regardless of whether they need it, or < 100% with a sensibly default. I don't see any argument for why this doesn't make sense, just people dismissing this fact and pointing out that not all of them work with the sensible default which I agree with and thus why it is a default and not only option.
Based on the approach in #3 it would seem one would have to include all the code I moved into the base class in EVERY handler in one form or another. If a single class then it would be in that class, and if two classes (more complex case) then in one of the classes. Again putting the code in the base class allows the complex case to override and everybody else not to have to copy and paste redundant code. Sounds like the entire point of object orientation? If the classes that need the extra class won't want the code that I moved then why would we want to force everyone else to copy-paste it for those that have not additional fields and what not part of all this?
We can use whatever method everyone likes for allowing the override, but again that was not the issue I was trying to solve...and the approach I took does not break the current implementation with the extra group_by class. We should create a separate issue to add the override code mentioned in #3, but they are separate topics.
Comment #5
merlinofchaos commentedAre you responding to what I actually said or are you knee-jerk responding to something else? Because your response makes no sense in the context of what I posted. I don't even know how to respond to it.
Comment #6
boombatower commentedI would ask the same and not sure what to clarify. Either what I write is not being digested or the responses given are not clear.
Using #3 alone:
Every single handler in existence will have to copy paste the code in views_handler_field_group_by_numeric in order to support group by, even if they list themselves as the group by handler (aka only one classes used for both).
The classes that need the special code like entity handlers and what not will need to write custom code anyway and won't be effected by this since they will override it.
Combination:
So what we need is #3 with the default set to the normal handler and all the code in group_by_numeric classes moved into their respective base classes.
Comment #7
boombatower commentedHow can I push this along?
Comment #8
boombatower commentedUpdated original patch against latest. Still need to add #3, but doesn't make anything worse, only improves since those who don't need custom work automatically.
Comment #9
boombatower commentedPatch would come in handy.
Comment #10
merlinofchaos commentedOkay, so one of the problems here is that you're going to get completely braindead output in most cases. The reason that we're switching to a different handler is that most group by functions can fundamentally change the data being presented.
Let's say I've got a simple query:
node.title is a string. It is run through check_plain, possibly made a link, and has whatever other string rendering we have on it.
COUNT(node.title), however, is a number. As a number, we need numeric handling on it. We need to allow the thousands marker to be specified.
Also, we absolutely do not want them to even be able to select "Link this title to its node". That has no meaning in this context.
Now, how is the normal node.title handler going to understand how to do this?
And I realize the situation we currently have is not ideal, but we still have to be able to handle this.
Comment #11
boombatower commentedOf the supported aggregation functions count is an oddball and if you look at the patch I left the numeric override handler on it.
SUM, AVG, MIN, MAX will all keep the same datatype and by definition only make sense when working with numeric data, but if you force the numeric handler then for instance in my usecase a timespan looses its formatting even though it is still a timespan. This will hold true for any numeric data that is formatted.
If I perform any of the operations on miles, time, weight, etc the units have to stay the same and thus using the same handler makes sense.
SUM: x + y (addition has same units)
AVG: (x + y) / n (addition requires same units and n has no units)
MIN: x (simply one element from a set, so no unit change possible)
MAX: x (see above)
COUNT: n (completely bypasses the data type and will never have units so numeric handler makes sense)
Comment #12
merlinofchaos commentedOne of these disagrees with the other. :)
Comment #13
merlinofchaos commentedAhh, I see. You changed it to the base numeric handler. That's a really subtle thing to see, since when looking at the patch, mostly I see the file being removed. Ugh.
Comment #14
boombatower commentedMaking a note here so I don't forget.
inclues/handlers.inc:256
Add the $this->query part since it will not always have a value with patch. Without this you get a fatal error attempting to export a view that is using grouping.
Comment #15
Shadlington commentedSubbing
Comment #16
kevinob11 commentedsubscribe
Comment #17
merlinofchaos commentedLet's try this updated patch. Group by aggregation actually works a lot better than I expected with the field api cleanup here:
Comment #18
merlinofchaos commentedI think I'm pretty close to just committing this.
Comment #19
merlinofchaos commentedI committed #18 last night.
Comment #20
boombatower commentedYea!
Comment #22
Peter Bex commentedI've also been bitten by this problem (incorrect group by on vid, nid) with Drupal 6.
Of course the patch doesn't apply, since it's for D7. Any chance for a patch for D6?
Comment #23
Peter Bex commentedOh, I guess http://drupal.org/node/695298 does the trick for D6