I marked this as 4.7, but I think this is still a problem in HEAD.
We have been struggling in views for several months with recurring problems of queries using from_unixtime that break when run through db_rewrite_sql. Earl suggested I try to get it down to the simplest possible reproducable use case and I have finally broken it down into a simple query using core tables that will always break:
<?php
$query = "SELECT * FROM {node} node LEFT JOIN {comments} comments ON node.nid = comments.nid WHERE from_UNIXTIME(node.created)";
$primary_table = 'node';
$primary_field = 'nid';
$query = db_rewrite_sql($query, $primary_table, $primary_field, array());
?>
The above query will return as:
SELECT * FROM {node} node LEFT JOIN {comments} comments ON DISTINCT(node.nid) = comments.nid WHERE from_UNIXTIME(node.created)
Which is, of course, invalid sql. The pattern I finally came up with that will break is a join of any two fields with a where clause that uses FROM_UNIXTIME. That's it. Remove the join and it works fine. Remove the FROM_UNIXTIME and it works fine.
I found numerous issues related to problems with FROM_UNIXTIME and an interesting one was http://drupal.org/node/28577 which suggested that maybe the 'FROM' in FROM_UNIXTIME was getting confused with the 'FROM' part of the query. That particular issue seems to be resolved, but it still might be a clue to the problem.
Other examples of reports of this problem:
http://drupal.org/node/49157
http://drupal.org/node/67927
http://drupal.org/node/76806
http://drupal.org/node/78027
Comment | File | Size | Author |
---|---|---|---|
#4 | from_unixtime.patch | 788 bytes | chx |
Comments
Comment #1
merlinofchaos CreditAttribution: merlinofchaos commentedThe issue in 28577 fixed it, but the whole thing was later rewritten and I think the FROM part is once again the culprit.
Comment #2
RayZ CreditAttribution: RayZ commentedHaven't tested, but this is likely fixed by the patch at http://drupal.org/node/80200.
Comment #3
RayZ CreditAttribution: RayZ commentedOops ... sorry, that was specific to pager_query(). Nevermind.
Comment #4
chx CreditAttribution: chx commentedThanks for the tip, the same idea is applicable here: let's look for a space after FROM.
Comment #5
KarenS CreditAttribution: KarenS commentedI can confirm this works in my test case.
Comment #6
Dries CreditAttribution: Dries commentedfrom_unixtime
is a MySQL-ism and shouldn't be used to begin with. It results in code that is incompatible with PostgreSQL (and with Drupal core in general).Tempted to mark this "won't fix".
Comment #7
webchickDries: That's true about the MySQL-ism but it's still a buggy regex. If ANSI SQL ever decided to introduce a function called FROMAGE() that turned values into cheese, the same problem would happen. ;)
Comment #8
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedpostgres users could easily define a function that is also named from_unixtime. IIRC Drupal used to define a pgsql IF function. Or was it GREATER?
Comment #9
drummSince this actually has nothing to do with FROM_UNIXTIME, it is any instance of 'FROM', this is okay. Still don't use FROM_UNIXTIME().
Committed to HEAD.
Comment #10
killes@www.drop.org CreditAttribution: killes@www.drop.org commentedalso to 4.7
Comment #11
(not verified) CreditAttribution: commented