I have an issue where an EntityFieldQuery executed for Anonymous users with the "node_access" tag error out due to an invalid "nid" column reference in the generated SQL.
My issue looks very similar to what is documented here https://drupal.org/node/1679646#comment-6849446. However, that issue was closed due to not being a bug in entityreference. Comment #16 suspects that the bug lies in node_access instead. Debugging the code, I believe the issue may lie in node_access as well. However, I'm somewhat skeptical of my own conclusions, simply because I think this would be affecting more people if it indeed was such a core-level bug.
By adding the "node_access" tag to the query, drupal hooks node_query_node_access_alter() on Line 3172 of node.module. This delegates to _node_query_node_access_alter($query, 'node'); Note that 'node' is hard-coded here, and thus can never be a different value when node_query_node_access_alter() is triggered by the "node_access" tag. Looking inside _node_query_node_access_alter(), there is a bunch of code, but the key piece to look at is Lines 3319-3326:
$field = 'nid';
// Now handle entities.
if ($type == 'entity') {
// Set a common alias for entities.
$base_alias = $nalias;
$field = 'entity_id';
}
$subquery->where("$nalias.$field = na.nid");$field is defaulted to 'nid', and since $type == 'node' (instead of 'entity') it remains 'nid'. Thus, the subquery WHERE clause assumes a column name of 'nid' for the table referenced by '$nalias'. However, the table referenced by $nalias, at least in my case, is a field table. Field tables dont have a 'nid' column, but instead have an 'entity_id' column. As such, the query throws an exception when executed.
In my case, I can probably remove the node_access tag from my EntityFieldQuery, instead opting for the 'entity_field_access' tag that is automatically added to it by the field_sql_storage module. But if I do that, then any other functions implementing hook_query_node_access_alter will be skipped for my EntityFieldQuery.
Comments
Comment #1
brettbirschbach commentedTo work around the issue, I added this admittedly horrible hack right below the calculation of $base_table in the _node_query_node_access_alter() function. This effectively causes the function to result in the same query condition as does node_query_entity_field_access_alter(). If the entity_field_access tag was specified, it's completely duplicate, but at least it doesn't break the query. This allows me to use the "node_access" tag on my EntityFieldQuery so that other node_access hooks can still be triggered.