I noticed when I have an argument validator and a filter that both restrict nodes returned based on the nodes having a certain term that there was a logic error in views_many_to_one_helper::ensure_my_table().
The table alias was being set as follows:
$this->handler->table . '_value_' . $count
but a new $count was done for each unique value of $field, not $this->handler->table, which should be what is used. That patch fixes this problem. An alternative approach would be to form the table alias name in a different way based on $field instead of $this->handler->table. So something like
$this->handler->table . '_' . $this->handler->field . '_value_' . $count
The later approach might result in prettier code, but I wasn't sure if it would cause other problems. Applying the attached patch fixes the problem I was having and doesn't seem to cause any additional problems, but I haven't tested thoroughly.
| Comment | File | Size | Author |
|---|---|---|---|
| views_ensure_my_table_many_to_one_0.patch | 1.5 KB | aclight |
Comments
Comment #1
merlinofchaos commentedUsing just the table as an identifier? That doesn't seem like it's safe; if you end up with queries on different fields within the same table don't you end up crossing things up?
Comment #2
aclight commentedHuh? That's what the code is currently doing (that is, using just the table plus a count as the identifier). The patch I uploaded doesn't change the way that the alias is created, other than it doesn't start counting from 0 with each table $field, as the current code does, but with each actual table that's used.
Comment #3
aclight commentedIt's been a week with no follow up on this issue. I don't know if that means that you've been busy with other things or if you still don't see what the problem is here. On the chance that it's the later, I thought I'd be a little more explicit as to the problem.
For both examples below let's use the following situation where views_many_to_one_helper::ensure_my_table() is called twice. The first time its called,
and the second time
These are real values that come from a custom relationship (first one) and the Term:tid filter that ships with views (second one).
The current relevant code is this:
So the first time this code is called, $this->handler->view->many_to_one_count[$field] will not be set, the counter will be set to 0, and therefore $this->handler->view->many_to_one_aliases[$field][$value] will be set to
term_node_value_0. That's all fine. But then the second time this is called, $this->handler->view->many_to_one_count[$field] will also be unset (because this time $field is 'tid' where before it was 'project_type_tid'. That means that a new counter will be used, and it will be reset to 0, and therefore the second time ensure_my_table() is called $this->handler->view->many_to_one_aliases[$field][$value] will again be set toterm_node_value_0.The reason is that only $this->handler->table is concatenated into a string to produce what will be the alias, and in this example both times this function is called this will be equal to "term_node".
Hopefully this clears up what the problem is.
Comment #4
merlinofchaos commentedAHHHH! I get it now. Man it took me a long time to zero in on what the problem was.
What if we used $handler->real_field instead of $handler->field? I am concerned that just using the table, if we have a single table where actually different fields are in use like this, we could get different collisions.
$handler->real_field should always be the unaliased field, which would allow this to work. What do you think?
(And yes, part of this is that I haven't had a lot of time; I'm trying to get Panels 3 out and right now I'm in a tough piece of work and being pulled in 8 different directiosn every day)
Comment #5
yched commentedRight, generating an alias string that discriminates different fields looks safer that storing $counts based on the table as the initial patch does. Wouldn't know for sure about using field vs real_field, though.
Comment #6
merlinofchaos commented$handler->real_field will always be the actual, unaliased field a handler thinks it belongs to assuming such a thing exists (and if it's using many::one it better exist).
Comment #7
marcp commentedI think what's missing from aclight's description in #3 is this, at the beginning of
views_many_to_one_helper::ensure_my_table():So, from his example, the first time through, $field is 'term_node.project_type_tid' and the second time through, $field is 'term_node.tid' which, since both fields are from the same table, should get them the same alias.
Comment #8
merlinofchaos commentedOk, finally convinced. This is now in.