Prior to installing Domain Access, I had a view set up that included a relationship. The nodes in the view ("events") had a node reference to a "location" node via a field named node_field_data_field_event_site. Most events had locations, but a few did not. This worked fine; events without locations still displayed in the view, because the "required" checkbox was not selected in the view releationship dialog.
After installing Domain Access, the view still worked for event nodes that had locations, but all events that were lacking locations were dropped from the view. The reason for this seems to be the node access check that Domain Access inserts into the view to insure that the node referenced in the view can be displayed in the current domain. Some of the inserted SQL appears below, the key part is the part that says: AND (node_field_data_field_event_site.nid = na.nid). If a location node exists, then there will be some node where this expression is true, and the condition will succeed. If there is no location node, though, then there will be no node where this expression matches, which will cause the entire EXISTS clause to return FALSE, excluding those nodes that do not have locations.
Note: Selecting "Disable SQL rewriting" did happen to work for this view, and I suppose this is semi-viable for this situation, because this particular view contains only objects that are visible to all users, and visible to every affiliate domain. However, I don't see this as a good long-term solution, because I will have other views that require node access, and some of these may have non-required relationships.
I can see why Domain Access is doing this in the general case, but it seems to me that the EXISTS clause is too rigorous for relationships that are not required. Maybe AND ( EXISTS ( ... ) OR (field = NULL) ) would be the right SQL to put in (sorry, not sure about the thing to test for when there is no relationship -- but that's the general idea). Is there an easy way to configure Domain Access &/or my view to generate SQL like this for non-required relationships, or is this a Domain Access bug?
Using Domain Access 7.x-3.9 and mysql 5.5.25 on Drupal 7.22.
$ drush pml --status=enabled | grep -i domain
Domain Access Domain Access (domain) Module 7.x-3.9
Domain Access Domain Alias (domain_alias) Module 7.x-3.9
Domain Access Domain Configuration (domain_conf) Module 7.x-3.9
Domain Access Domain Navigation (domain_nav) Module 7.x-3.9
Domain Access Domain Settings (domain_settings) Module 7.x-3.9
Domain Access Domain Source (domain_source) Module 7.x-3.9
Domain Access Domain Theme (domain_theme) Module 7.x-3.9
Domain Access Domain Views (domain_views) Module 7.x-1.5
Here's a larger part of the SQL that was added by Domain access.
AND
(
EXISTS
(
SELECT
na.nid AS nid FROM drupal_node_access na
WHERE
(
(
(na.gid = :db_condition_placeholder_14)
AND
(na.realm = :db_condition_placeholder_15)
)
OR
(
(na.gid = :db_condition_placeholder_16)
AND
(na.realm = :db_condition_placeholder_17)
)
OR
(
(na.gid = :db_condition_placeholder_18)
AND
(na.realm = :db_condition_placeholder_19)
)
OR
(
(na.gid = :db_condition_placeholder_20)
AND
(na.realm = :db_condition_placeholder_21)
)
)
AND
(na.grant_view >= :db_condition_placeholder_22)
AND
(node_field_data_field_event_site.nid = na.nid)
)
)
Comments
Comment #1
greg.1.anderson commentedLooking into this a bit more, it appears that this is not a Domain Access-specific problem, but applies to any Node Access module used in conjunction with views that have non-required node relationships. Investigating Drupal's node_access() implementation a bit, I see that the entire EXISTS clause above is inserted by
_node_query_node_access_alter(). This is just fired off via a call to->addTag('node_access');somewhere in views.I know that I could adjust the OR clauses via hook_node_grants_alter, but this does not help me. It also seems that there is little views can do here; the node_field_data_field_event_site.nid term is also added in
_node_query_node_access_alter(), and all of the tables in the SQL query (in this case, the primary node for the view, and the node for the views relationship) are handled equivalently by iterating over$query->getTables().The only idea I have right now is to add a feature to node.module where
_node_query_node_access_alter()could use$query->getMetaData()to fetch a new, optional metadata item to indicate which tables are "optional", and insert the "OR null" conditional suggested in #0 for those tables mentioned in the list. Views could then use this feature to mark views relationship tables as "optional" if the "required" option is not specified.I searched through the views queue; this may be a duplicate of #1349080: node_access filters out accessible nodes when node is left joined.
Comment #2
mustanggb commented