This bug was originally reported by jyang about the OG module, but probably will also appear with any other module which implements node_access restrictions. I talked with merlinofchaos about this, and he says that this issue is both specific to MySQL 5 and also should be filed against the core statistics module, so that's what I'm doing. ;)
When you have a module enabled that implements node_acess restrictions, you'll receive the following as a non-uid 1 user:
user warning: Unknown column 'n.nid' in 'on clause' query: SELECT DISTINCT(n.nid), n.title, u.uid, u.name FROM node_counter s INNER JOIN node_access na ON na.nid = n.nid INNER JOIN node n ON s.nid = n.nid INNER JOIN users u ON n.uid = u.uid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all') OR (na.gid = 0 AND na.realm = 'og_public') OR (na.gid = 0 AND na.realm = 'og_all'))) AND s.daycount '0' AND n.status = 1 ORDER BY s.daycount DESC LIMIT 0, 3 in C:\progs\web\Apache\Apache2\htdocs\Drupal\drupal-4.7.0-beta4\includes\database.mysql.inc on line 124.
This error occurs because a join is done on node_access before node comes into the picture.
Re-ordering the first two tables in statistics_title_list query seems to solve this problem. This is because then the node table comes first and the join happens in the correct place. A patch is attached.
Comment | File | Size | Author |
---|---|---|---|
#39 | db_rewrite_sql_4.patch | 7.51 KB | webchick |
#33 | db_rewrite-with-taxonomy_0.patch | 7.14 KB | chx |
#30 | db_rewrite-with-taxonomy.patch | 7.13 KB | merlinofchaos |
#16 | db_rewrite_nail_2.patch | 2.78 KB | chx |
#12 | forum_19.patch | 1.66 KB | webchick |
Comments
Comment #1
webchickActually I found another of these in forum.module's forum_get_topics:
This yields the following error when viewing ?q=forum when OG module's node_access control is enabled:
No idea how to fix this one though; moving {node} n to the start of the query didn't seem to help. :\
I suspect that this same issue will arise on all taxonomy-related db_rewrite_sql queries as well if {term_data} is not the first table listed.
Comment #2
webchickLet's go with a more descriptive title.
Comment #3
Dries CreditAttribution: Dries commentedCommitted to HEAD. Marking this active because the forum.module problem is still present.
Comment #4
moshe weitzman CreditAttribution: moshe weitzman commentedThese forum.module queries are unlike any other in drupal. I traced their introduction to this diff [1] and this issue [2]. the user ccourtne engineered these queries for us. he is not accepting contacts via drupal.org. anyone know how to contact him? . I see this comment above one of the queries:
// This query does not use full ANSI syntax since MySQL 3.x does not support
// table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria
In that issue, the patch before the one that was commitrted used more conventional SQL but apparently did not work on Mysql3. So one option here would be to change HEAD accordingly and drop mysql 3 support. I wouldn't mind seeing that happen anyway. But hopefully we don't need to do that. Anyone care to jump in here?
Comment #5
chx CreditAttribution: chx commentedThis patch radically changes db_rewrite_sql -- for good. It moves the JOIN just before the first thing after the JOINs. If you come to think of SQL syntax, that is just what we use for WHEREs. Hence the patch.
Comment #6
rjl CreditAttribution: rjl commentedmy comments here may be moot due to chx's patch, but I thought I should share them none the less
First, IMHO I don't believe this is a node access problem. I think this is a db_rewrite_sql() and hook_db_rewrite_sql() problem.
These sql errors may show up on any site that has a module that implements hook_db_rewrite_sql(). When the hook is implemented the developer of the module defines what logic is needed, and if those defined logical parameters are meet, the hook will change queries passed thru the db_rewrite_sql() function.
example #1: see http://drupal.org/node/44291, the logic here is related to the value returned by a call to user_access('xxx'), if FALSE is returned the hook will change the query.
example #2: see http://drupaldocs.org/api/4.6/function/hook_db_rewrite_sql, the logic here is to change all the queries
There are a few reasons this is largely thought of as a node access problem:
1. the node module implements hook_db_rewrite_sql (you can also think of this as example #3) The logic here is related to the return value of the node_access_view_all_nodes() function. If TRUE, it doesn't do anything, if FALSE, then the hook changes the queries to include this join clause: "INNER JOIN node_access na ON na.nid = n.nid"
2. hook_db_rewrite_sql() is not a commonly implemented hook (it's difficult to name another module that implements it).
3. It hasn't been a problem until MySQL 5.0, so it's really just starting to show up.
Second, I want to help with this but am not sure what to do exactly.
This issue has been posted in several places (with forum module, with event module, with image module, on the development mailing list, and now here). This is a problem in both 4.6 and 4.7. I think some bigger discussion needs to happen about db_rewrite_sql() and hook_db_rewrite_sql() and their limitations. Once descisions are made about those functions, then we will better know how to procede in terms of what other modules need to do in terms of using db_rewrite_sql(). Then we will what patches are needed. As someone fairly new to drupal, I don't really understand how the whole core development part works and the chain of command and the descision making process, and this is why I am not sure what to do to help. Your advice would be invaluable.
In the immediate term though, here is a rewrite of the query for webchick's problem above that I think should do the trick
Comment #7
rjl CreditAttribution: rjl commentedsorry, didn't know my previos post changed the whole issue title (I get confused and think I am commenting) this post just changes the title back to chx's suggestion
Comment #8
chx CreditAttribution: chx commentedrjl , if you can, please test my patch.
Comment #9
chx CreditAttribution: chx commentedFurther simplification.
Comment #10
chx CreditAttribution: chx commentedFurther simplification.
Comment #11
webchickSorry, chx... :( The error remains on ?q=forum even with this patch applied. I emptied my cache too on the off-chance that this was somehow related to that.
A user is also having all sorts of problems with OG and OG_forum, a module that uses db_rewrite_sql on taxonomy queries. http://drupal.org/node/52012. This may be due to a bug in that module though rather than another instance of the same problem only on the taxonomy rewrite side.
I tried testing taxonomy_access as a 'second opinion', but I don't think it's been updated to HEAD yet; I get array errors when I try and change any category permissions.
Comment #12
webchickI can confirm though that rjl's changed query does in fact work (though no idea what it does to MySQL 3.x). Here is a patch.
However, I think he is right that this method is only attacking symptoms rather than the root cause. So I'm hoping chx can whip up something to fix this @ the db_rewrite_sql level rather than having to constantly hunt and peck for these troublesome queries.
Comment #13
Cvbge CreditAttribution: Cvbge commented@chx: part of the patch seems wrong
Comment #14
Cvbge CreditAttribution: Cvbge commentedSorry, my mistake.
Comment #15
rjl CreditAttribution: rjl commentedI would argue against changing the function at all
Noting the parameters of the function:
There are 4: $query, $primary_table, $primary_field, $args
Noting the functionality of hook_db_rewrite_sql...
In 4.6 it only allows for nodes (see http://drupaldocs.org/api/4.6/function/hook_db_rewrite_sql)
In 4.7 (head) it adds vocabularies, terms and comments (see http://drupaldocs.org/api/head/function/hook_db_rewrite_sql)
The description for the hook says this about what values may be passed as $primary_table and $primary_field
For node objects, primary field is always called nid. For taxonomy terms, it is tid and for vocabularies it is vid. For comments, it is cid. Primary table is the table where the primary object (node, file, term_node etc.) is.
Regarding the db_rewrite_sql function see
in 4.6 (http://drupaldocs.org/api/4.6/function/db_rewrite_sql)
in 4.7 (head) (http://drupaldocs.org/api/head/function/db_rewrite_sql)
the $primary_field parameter is defined as follows
$primary_field Name of the primary field.
This should be as specific as the hook says above and should specifically state the same 4 fields that can be used, so that developers know what is allowed without having to hunt down the hook.
the $primary_table parameter is defined as follows
$primary_table Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, term_data, vocabulary.
I IMHO believe this is way to open. I think $primary_table should be limited to specific tables the same way $primary_field is. My suggestion would be "n" for node, "td" for term_data "v" for vocabulary, "c" for comment. And not allow any other tables, period.
Also I would add the following limitations for the value of $query.
The $primary_table must be the first table listed in the FROM clause
Implied cross joins are disallowed (ie queries like this: FROM {node} n, {users} u must be this: FROM {node} n INNER|LEFT|RIGHT JOIN {users} u ON ...)
The only change needed to the code would be slight changes to the function descriptions and paramenter definitions, and this is why I don't think the function itself really needs a patch at all
IMHO, this function works really great and is one of the most amazing aspects of drupal.
Comment #16
chx CreditAttribution: chx commentedWhile my patch is needed so that we do not suffer from the order of JOINs the above me is totally right -- it seems that FROM x , y INNER JOIN boo ON x.f1 = boo.f1 does not work under MYSQL5 because this to JOIN on table y and x is nowhere to be seen.
Yes, implicit JOINs are not to be used. Upgraded doxygen, will upgrade the handbook later, merged webchick's patch into mine.
Comment #17
chx CreditAttribution: chx commentedsomeone please test that if you revert http://drupal.org/files/issues/statistics-node_access.patch stats still work, I have no time for that. If it does, then my patch is good and solves all such issues.
Comment #18
dwwi applied your patch against includes/database.inc and reverted modules/project/issue.inc to revision 1.145 (revision 1.146 was a patch i recently made to fix this problem via reordering the SQL handed to db_rewrite_sql() so the {node} table came first). i tried viewing some project issues as an anonymous user with node_privacy_byrole enabled. my test environment with issue.inc revision 1.145 failed without your patch and worked once i applied it. so your changes to db_rewrite_sql() appear to be good! i haven't tested the changes to forum that your patch makes, so i'm not going to set the status of this to "ready to commit". but, it appears the main bug is finally solved. thanks much!! at last, there appears to be an end in sight to my long nightmare of porting drupal modules to MySQL 5.0.12+. :)
-derek
Comment #19
dwwsorry i left this out...just to be clear: i tested db_rewrite_nail_2.patch (2.78 KB)
Comment #20
webchickOk. I reverse-applied my initial patch on my OG HEAD install, and confirmed that I still get the page full of errors with the popular content block enabled.
Applied chx's latest patch and they magically disappear! :D Between that and the forum query patch, it seems to have solved all the issues I previously found with OG. So, woohoo!
*HOWEVER* ;) I tried enabling og_forum module, which is a module that uses db_rewrite_sql on taxonomy tables, and came up the following error on node/add/forum:
user warning: Unknown column 't.tid' in 'on clause' query: SELECT DISTINCT(t.tid), t.*, parent FROM term_data t, term_hierarchy h LEFT JOIN og_term ogt ON t.tid = ogt.tid LEFT JOIN og_uid ogu ON ogt.nid = ogu.nid AND ogu.uid = 1 AND t.tid = h.tid AND t.vid = 1 ORDER BY weight, name in D:\xampplite\htdocs\og-head\includes\database.mysql.inc on line 120.
I believe this is the 'implcit join' problem that dww pointed out, as well as the primary table (term_data) not being listed first. I surfed through taxonomy.module and it looks like there are *a lot* of these:
taxonomy_get_tree: < this is the one that caused the error earlier
SELECT t.tid, t.*, parent FROM {term_data} t, {term_hierarchy} h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name
taxonomy_get_parents:
SELECT t.tid, t.* FROM {term_hierarchy} h, {term_data} t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name
taxonomy_get_children:
SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE t.vid = %d AND h.tid = t.tid AND h.parent = %d ORDER BY weight, name
SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE h.tid = t.tid AND parent = %d ORDER BY weight, name
taxonomy_node_get_terms_by_vocabulary:
'SELECT t.tid, t.* FROM {term_data} t, {term_node} r WHERE t.tid = r.tid AND t.vid = %d AND r.nid = %d ORDER BY weight', 't', 'tid'
taxonomy_term_count_nodes:
SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t, {node} n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid
I was going to rewrite them myself, but I'm not sure a) if some of these are false positives and b) what type of JOIN to use in each case (my SQL is shamefully rusty in this area).
In conclusion :P
chx's patch seems to work, and should mitigate a lot of these types of errors. However, taxonomy module's rewrite queries (at least one of them) needs some love. Should I file a separate issue for those, or should we use this issue to try and 'nail' all of these rewrite queries in HEAD in one go?
Comment #21
jyang CreditAttribution: jyang commentedI just wan to draw your attention to the following error report for using OG module:
http://drupal.org/node/52012
Comment #22
rjl CreditAttribution: rjl commentedthoughts on the og module problems
on line 626
This could potentially be a problem:
note the 2nd argument ($primary_table) 'og' for the db_rewrite_sql() function. Why not use 'n' as the node table is present in the query?
on lines 1409 and 1410
This could also potentially be a problem if joining the node_access table returns more records than the query without the join does. The distinct logic won't kick in for this query.
the implementation of hook_db_rewrite_sql()
Given the logic, it is possible to output the WHERE conditions without the JOIN (this seems to be the problem jyang is having). I think that both the join and where functionality be wrapped in your 2nd if statement
Comment #23
rjl CreditAttribution: rjl commentedI think chx's patch is great and nice to see that the order of the joins shouldn't then matter. It makes it a better function.
One more question?
What about restricting the values allowed for the $primary_table value?
The reason I ask is that in my post above regarding the og module, the first section notes use of 'og' as the value of the $primary_table. If I have two modules that that implement hook_db_rewrite_sql and perform the check exampled in drupaldocs for the hook (on one of my sites I currently have this situation).
The resulting join (using the og module join as example) would be
FROM {og} og INNER JOIN {node} n ON og.nid = n.nid INNER JOIN {node} n ON og.nid=n.nid INNER JOIN {node} n ON og.nid = n.nid INNER JOIN {node_revisions} r ON r.vid = n.vid INNER JOIN {users} u ON n.uid = u.uid
This will provide a non-unique alias SQL error for using the alias "n" multiple times
Thanks
Randall
Comment #24
rjl CreditAttribution: rjl commentedSorry, the resulting join (using the og module join as example) would acutally be
FROM {og} og INNER JOIN {node} n ON og.nid = n.nid INNER JOIN {node_revisions} r ON r.vid = n.vid INNER JOIN {users} u ON n.uid = u.uid LEFTJOIN {node} n ON og.nid=n.nid LEFT JOIN {node} n ON og.nid = n.nid
None the less, it will still provide a non-unique alias SQL error for using the alias "n" multiple times
Comment #25
chx CreditAttribution: chx commentedMy patch _is_ good to go. I am asking the committer to reset the issue to active once it's in and we will cook a patch for the remaining taxo queries.
Comment #26
Montuelle CreditAttribution: Montuelle commentedI had also had the error
Unknown column 'n.nid'
when enabling Organic Group. Db_rewrite_nail_2.patch fixed the problem.Comment #27
Dries CreditAttribution: Dries commentedLet's first figure out the problem with the remaining taxonomy queries ...
Why did we still had to rewrite the forum.module query? Isn't the parser smart enough?
Comment #28
chx CreditAttribution: chx commentedI explained it above: FROM x , y INNER JOIN boo ON x.f1 = boo.f1 does not work under MYSQL5 because this to JOIN on table y and x is nowhere to be seen.
It's not my parser. The above query would fail written by humans. Simply, you can not use the FROM x, y syntax.
Comment #29
chx CreditAttribution: chx commentedComment #30
merlinofchaos CreditAttribution: merlinofchaos commentedI redid the taxonomy queries as requested, and rolled it into chx's patch. I have not had the time to test the queries, but they are all quite straightforward. Please review.
Comment #31
chx CreditAttribution: chx commentedComment #32
jyang CreditAttribution: jyang commentedI applied the patch, so far it seems all the errors are gone, thank you all for the hard work.
Comment #33
chx CreditAttribution: chx commentedI revised the system and much to my surprise I found lines like:
What I've been smoking?
Comment #34
jyang CreditAttribution: jyang commentedJust wondering if this is also good?
- $query .= ' WHERE '. $where;
+ $query .= $new;
Thanks
Comment #35
chx CreditAttribution: chx commentedyes, that's good.
Comment #36
jyang CreditAttribution: jyang commentedSorry, I mean the dot "." in front of equal sigh?
Comment #37
webchickjyang: Yes. .= means "add this string to that string"
I will try and test this a bit later. Thanks a lot for all of your work, guys!
Comment #38
Dries CreditAttribution: Dries commentedCode looks good. Needs significant testing.
Comment #39
webchickTested everything I could think of for the taxonomy portion:
- Add/edit/delete a vocabulary
- Add/list/edit/delete terms (including a hierarchy of terms)
- Creating content assigned to multiple terms, verified I could pull up content by terms
- Created free-tagging vocabulary, verified I could pull up content by terms
- Created forum topics
All seemed to work fine.
og_forum produced the following error when creating a group:
Cannot use a scalar value as an array in D:\xampp\htdocs\og-head\modules\taxonomy.module on line 440
However, this seems like it is more likely a bug in og_forum as there are no select queries anywhere near line 440 (which is the following line in taxonomy_save_term: $edit['parent'] = array(0);) This might've been caused by recent changes to the OG module. Any idea if there is another module that uses taxonomy db_rewrite_sql queries someone could test with?
Btw, here is a re-rolled patch which should apply cleanly and isn't in some strange b/ directory.
Comment #40
webchickYeah, chx helped me do some troubleshooting and it is indeed a bug in og_forum someplace. I'll look when I'm more awake. :P
In the meantime, setting this RTBC.
Comment #41
dwwi re-tested the problem with MySQL 5, and updated HEAD drupal install, revision 1.145 of modules/project/issue.inc (which has the known-broken SQL query) and db_rewrite_sql_4.patch (7.51 KB). once again, before the patch, the query died and nothing worked when trying to view project issues as an anonymous user. after the patch, everything's fine.
further evidence that this patch is RTBC.
thanks,
-derek
Comment #42
Dries CreditAttribution: Dries commentedCommitted to HEAD. Thanks. Great work!
Comment #43
yktdan CreditAttribution: yktdan commentedIs someone going to test and commit this to the 4.6 tree? Currently anyone on 4.6 and MySQL 5.0.12+ is dead.
Comment #44
(not verified) CreditAttribution: commentedComment #45
dwwi noticed this issue got automatically closed by cron (since the cvs version of it has been fixed). however, this is still broken in 4.6.6. i don't know if this should be marked as "won't fix" (which would be a shame), but at this point, i think we should re-roll this patch for 4.6 and commit it. i won't spend any time on this until someone in a position of authority marks it to "code needs work". if it's set as "won't fix", i won't press the issue, but i think drupal core should *definitely* support MySQL 5.0.12+, and we really need this patch for that to be true. so please, set this to "code needs work" and i'll see what i can do.
thanks,
-derek
Comment #46
webchickJust a note. The taxonomy rewrite queries don't exist in 4.6, so only the forum/statistics module ones need to be re-rolled (I think).
Comment #47
dwwand many contrib modules have been patched, 1-by-1, to be MySQL compliant in the face of the old db_rewrite_sql() behavior, too. i suppose we don't care about changing core in a stable release to make it easier for contrib modules to get this right. so, yeah, minimum new patch would be to manually re-order the remaining core queries (i'd have to look for them to be sure, but webchick, you're probably right that it's only forum + statistics at this point). given the effort that went into the fundamental fix to db_rewrite_sql(), and given that i can't imagine how that's really 4.7-specific, i'd be in favor of including that change in 4.6, too. but, as i said, i can see why people would be hesitant to do that, and i'd be willing to live with 4.6 == manually reordered queries and >=4.7 == works like a charm. ;)
thanks,
-derek
Comment #48
webchickOops! I forgot about the change to db_rewrite_sql at the core level. Yeah that should probably be in there too.
Comment #49
magico CreditAttribution: magico commentedAfter closing another issue about this problem, we really need to resolve this problem!
@dww: take a look at the (now marked duplicated) issue http://drupal.org/node/49430
@chx: what can be done?
Should we mark this as "won't fix" and state that Drupal 4.6.x *DOES NOT* work with mysql 5.x ?
Comment #50
admin@thanetcouncil.info CreditAttribution: admin@thanetcouncil.info commentedI'm sorry I am a usless morronic idiot
I have no idea what to do with that "patch file"
And before I get some php developer clique answer that I will be unable to understand I'm an utterly useless fat, pathetic, n00b, dickhead moron fishfaced spam brain who still can only use that broken and worthless OS Windows
I appologise if my stench offends you "gods".
Comment #51
admin@thanetcouncil.info CreditAttribution: admin@thanetcouncil.info commentedand anyway you are wrong about 4.1.18-standard
Comment #52
chx CreditAttribution: chx commentedWe are slipping off topic so please do NOT answer but there is a handbook page aboutappling patches on Windows.
Comment #53
chx CreditAttribution: chx commentedComment #54
Paul Natsuo Kishimoto CreditAttribution: Paul Natsuo Kishimoto commentedComment #55
magico CreditAttribution: magico commentedGiving this a final shot! Is there anyone using Drupal 4.6 with mysql5 or need to?
According to dww at #47, is there anyone with some authority to take a decision about this?
Comment #56
Paul Natsuo Kishimoto CreditAttribution: Paul Natsuo Kishimoto commented@magico: I believe this is now "won't fix" with the 5.0 release. Closing, but feel free to reopen -)
Comment #57
yngens CreditAttribution: yngens commentedhad a bad luck to install private nodes module on a production site with Drupal5.x and MySQL5 and can't get rid of the exactly same message. so the problem still persists.
Comment #58
drummyngens - there were numerous queries which were revised and might be producing various subtly different error messages. Please paste the specific problem and any steps needed to reproduce.
Any chance this is a duplicate of http://drupal.org/node/183012?
Comment #59
yngens CreditAttribution: yngens commenteddrumm, i have solved my problem here: http://drupal.org/node/250615
thank you
Comment #60
NoRandom CreditAttribution: NoRandom commentedSame problem here with Drupal 5.10 and Refine by taxonomy 5.x 0.1 (http://drupal.org/node/230460). The curious thing is it works perfectly with Firefox 3.0 but I get twice the same error with Internet Explorer 6:
Comment #61
Summit CreditAttribution: Summit commentedHi,
Will this be committed in Drupal 5.11 please (after current version 5.10)?
On different places I have this error. And it seems that the error is there because of MYSQL 5 differences with MYSQL 4.
Off course every module builder can alter their module, but is it not better to commit the patch here?
Greetings,
Martijn
Comment #62
kenorb CreditAttribution: kenorb commented#331651: db_rewrite_sql improperly rewriting a subquery