I have a site with a news content type with a 'published' date field. There's an autocomplete entity reference field on a bean that refers to nodes of this content type, sorted by that field. The attached screenshot might make this a little more clear.

When logged in as an administrator, I'll see multiple nodes when I start typing in the autocomplete field, but when logged in as a user with enough access to create the bean, I'll only see a single node in the autocomplete list, even when I know other nodes should be there.

A little digging seems to implicate EntityReference_SelectionHandler_Generic::ensureBaseTable() in EntityReference_SelectionHandler_Generic.class.php.

That method is called from EntityReference_SelectionHandler_Generic_node::entityFieldQueryAlter() when there is no node_grants implementation and the current user does not have 'bypass node access' permission. This line is the culprit, and it is run in my tests when I'm logged in as the non-admin user:

$base_table = $this->ensureBaseTable($query);

As far as I can tell (EntityFieldQueries are hard to debug), the ensureBaseTable() method accidentally adds a second join to the node table, and the result set is a cartesian product of some kind.

This is the autocomplete list query generated as the admin user:

SELECT field_data_field_published_date0.entity_type AS entity_type, field_data_field_published_date0.entity_id AS entity_id, field_data_field_published_date0.revision_id AS revision_id, field_data_field_published_date0.bundle AS bundle
FROM
field_data_field_published_date field_data_field_published_date0
INNER JOIN node node ON node.nid = field_data_field_published_date0.entity_id
WHERE  (field_data_field_published_date0.deleted = '0') AND (node.title LIKE '%research%' ESCAPE '\\') AND (field_data_field_published_date0.entity_type = 'node') AND (field_data_field_published_date0.bundle IN  ('cals_news'))
ORDER BY field_data_field_published_date0.field_published_date_value DESC
LIMIT 10 OFFSET 0

When I run the above query, I get 6 rows back.

And this is the query generated by the user without 'bypass node access'. It has been run through ensureBaseTable() and a second join on the node table is present.

SELECT field_data_field_published_date0.entity_type AS entity_type, field_data_field_published_date0.entity_id AS entity_id, field_data_field_published_date0.revision_id AS revision_id, field_data_field_published_date0.bundle AS bundle
FROM
field_data_field_published_date field_data_field_published_date0
INNER JOIN node node ON node.nid = field_data_field_published_date0.entity_id
INNER JOIN node node_2 ON node.nid = field_data_field_published_date0.entity_id
WHERE  (field_data_field_published_date0.deleted = '0') AND (node.title LIKE '%research%' ESCAPE '\\') AND (field_data_field_published_date0.entity_type = 'node') AND (field_data_field_published_date0.bundle IN  ('cals_news')) AND (node_2.status = '1')
ORDER BY field_data_field_published_date0.field_published_date_value DESC
LIMIT 10 OFFSET 0

When I run this query without the LIMIT, I get back over 600 rows. Since the top ten all refer to the same node, my non-admin users end up seeing only that one node.

So my guess is that ensureBaseTable() isn't working right. I haven't dug any deeper than that, and I suspect others may know better than I how to properly detect the base table.

Files: 
CommentFileSizeAuthor
#2 1917560-entityreference-wrong-join.patch754 bytesDamien Tournoud
PASSED: [[SimpleTest]]: [MySQL] 119 pass(es).
[ View ]

Comments

INNER JOIN node node ON node.nid = field_data_field_published_date0.entity_id
INNER JOIN node node_2 ON node.nid = field_data_field_published_date0.entity_id

The problem is in the condition of the second query. It should be node_2.nid = field_data_field_published_date0.entity_id. As a consequence, the second join matches all the rows of the node table.

Status:Active» Needs review
Issue tags:+Needs tests
StatusFileSize
new754 bytes
PASSED: [[SimpleTest]]: [MySQL] 119 pass(es).
[ View ]

Does this help? Obviously we are missing tests on this.

Priority:Normal» Major

Status:Needs review» Reviewed & tested by the community

That nice, simple patch fixes the issue for me. Thanks!

Status:Reviewed & tested by the community» Fixed

Merged into 7.x-1.x.

Status:Fixed» Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.