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

brettbirschbach’s picture

To 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.

if ($type == 'node') {
    if (strcmp(substr($base_table, 0, 11), 'field_data_') === 0
        || strcmp(substr($base_table, 0, 15), 'field_revision_') === 0) {
      $type = 'entity';
    }
  }

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.