In hook_views_query_alter, how to add a condition which is a correlated subquery in which the value of the condition is an expression?
Given a view the produces this query:
SELECT node.nid, node.title, history.state
FROM node n
LEFT JOIN node_revision nr ON n.vid = nr.vid
INNER JOIN history h ON nr.vid = h.vid
WHERE (( (node.type IN ('blog')) ))
In order to show only the latest [state] for a given version (vid) of a node, we need to add this condition:
AND h.hid = (select max(hid) from history h2
where h2.nid = n.nid
and h2.vid = n.vid group by h.nid, h.vid)
So here's the statement we'd like to end up with after hook_views_query_alter:
SELECT node.nid, node.title, history.state
FROM node n
LEFT JOIN node_revision nr ON n.vid = nr.vid
INNER JOIN history h ON nr.vid = h.vid
WHERE (( (node.type IN ('blog')) ))
AND h.hid = (select max(hid) from history h2
where h2.nid = n.nid
and h2.vid = n.vid
group by h.nid, h.vid)
So we can see that our modified sql works, so here's our attempt (not working) to modify the statement on the fly:
function mymodule_views_query_alter($view, $query) {
if ($view->name == 'my_view') {
$expression = '(select max(hid) from
workbench_moderation_node_history h
where h.nid = node.nid
and h.vid = node.vid
group by h.nid, h.vid)';
$condition = array();
$condition['field'] = 'history.hid';
$condition['value'][] = $expression;
$condition['operator'] = '=';
$query->where[1]['conditions'][] = $condition;
}
}
This doesn't work (with or without the parenthesis) because the condition is an expression, not a value. To validate that the syntax of adding a condition is correct, this will at least return results:
function mymodule_views_query_alter($view, $query) {
if ($view->name == 'my_view') {
$condition = array();
$condition['field'] = 'history.hid';
$condition['value'][] = '1';
$condition['operator'] = '>';
$query->where[1]['conditions'][] = $condition;
}
}
How might we go about coding this constraint?