Closed (fixed)
Project:
Views (for Drupal 7)
Version:
5.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
8 May 2007 at 19:17 UTC
Updated:
31 Jul 2007 at 02:45 UTC
hook_views_tables_alter is great.... but the current implementation has a slight bug that prevents modules from adding new tables in the alter phase. The problem is that after hook_views_tables() is run, the data is stored in an array. The hook_views_alter_tables() hook is run on a copy, and the original is used as the basis for saving all the data.
The fix is just to move when the $table_data is assigned to $view_tables['tables'].
Attached is a patch that does just that.
| Comment | File | Size | Author |
|---|---|---|---|
| views_20070508_hook_table_alter.patch | 906 bytes | mfredrickson |
Comments
Comment #1
moshe weitzman commentedwhats the use case for adding a table during alter? why not add it during hook_views_tables()? just wondering.
Comment #2
mfredrickson commentedThe use case is bio.module. The bio module selects a node type to use as a "profile". I'm adding views support such that we can ask questions like: "show me all the blog posts by authors who have tagged their bio node with the term 'foo'"
To do this, I'm joining the node table against itself (
node node LEFT JOIN node bio ON node.uid = bio.uid AND bio.type = 'bio'). Then I'm copying every other table and prefixing it with 'bio' (e.g. 'bio_term_data', 'bio_node_data_field_some_cck_field'). This way, I can search the cck fields, taxonomy terms, etc of the bio node, but return a list of blog posts, e.g.So going in the tables array might look like:
Coming out it will look like:
I cannot do this in hook_views_tables() because I need to know everyone else's table definitions. I could call
module_invoke_all('views_tables')from within hook_views_tables, but that sounds like a path to weird recursion issues. What if some other module did this? Mutual recursion is hard to track down. I think the appropriate behavior is to add my pseudo-tables in the alter hook.Comment #3
moshe weitzman commentedthanks mark. i have no problem with this patch. we'll see what earl says.
Comment #4
mfredrickson commentedI'm going to self-upgrade this to RTBC. I'll call Moshe's endorsement a review as the patch is all of two lines.
Earl, thoughts?
Comment #5
moshe weitzman commentedOh mercy - thats gonna make the table definition array even bigger. The serialize and unserialize of this data, and even moving it around with mysql, can cause errors, especially on sites with many CCK fields. Causes out of memory errors, and some maximum packet size error on mysql. I think this patch should still go in though.
Comment #6
mfredrickson commentedYou bet. I just recreated the same technique that I used for bio, but using CCK's node reference fields as the join instead. I broke MySQL's brain (max_allowed_packet size exceeded 1mb, which was my test boxes (reasonable) default).
Long term, I think we need to pull apart cck table definitions into tables and aliases/joins. Each table can have fields, sorts, filters. The aliases would indicate which table they apply to and perhaps include additional fields, sorts, and filters that combine data from across the join. Then we could link up these tables and aliases to create the join trees.
Eg. let's say we have tables node and comment, and a join of comment->node on nid Then I create an alias "bio" of node that joins against the node table based on uid. Then, the autolinker sees that the bio alias is in fact the node table, and creates the alias for bio_comment on the fly based on the join info object.
Or something of this nature. Cloning the entire tree and grafting it back on it on will not scale.
Plus, this is execution order dependent, which I always hate. Combing my node reference joins with bio joins is going to be unpredictable - as one will go before the other.
Comment #7
moshe weitzman commentedand if that plan isn't fuzzy enough, we have an effort to add join information to our schema in core - http://groups.drupal.org/node/4328. this surely duplicates some Views information. In fact, it looks to me like modules should enrich the schema definition with views specific fields in order to do what they do now in hook_views_tables(). hmmm.
Comment #8
merlinofchaos commentedI'm not really thrilled with this. THere are people for whom Views crashes because it is storing too much data.
But I can see why you're doing it. So I've applied it, but please, be careful with bio module using this.
Comment #9
mfredrickson commentedWith great power comes great responsibility. :-)
That said, in the current views implementation I'm hard pressed to see another solution. If views separated the table definitions (ie. fields, filters, and sorts) from the aliases, this could be simpler. I.e. if I could say that "bio" is just the node table based on a join, I wouldn't have to copy and graft the entire tree to itself. That could be computed at run time, instead of storing it in a data structure.
I'm assuming views will switch to the schema API in D6. I think there are a lot of opportunities to improve this code when that happens.
Thanks for committing,
-M
Comment #10
(not verified) commented