Skip to content

[5.x]: Entry field queries returning _all entries_ if the id() param is used to exclude entry IDs #15570

@mmikkel

Description

@mmikkel

What happened?

Description

Since upgrading from 5.2.10 to 5.3.4, I'm seeing some odd behaviour with entry queries derived from Entries fields, where adding an .id(['not', id) param to the entry field query results in the query returning every single (non-nested) entry in the site (except the one(s) with the excluded ID(s)), i.e. completely disregarding the actual relations in the field.

Prior to 5.3.4, this query would return entries related to entry in the field entriesField, except an entry with the ID 23432234:

{% set entries = entry.entriesField.id(['not', 23432234]).all() %}

On 5.3.4, the above query will return all entries in the site (except any with the ID 23432234).

Crucially, this only appears to happen if the source entry has been re-saved after upgrading to 5.3.4. I.e. immediately after upgrading to 5.3 things work as before, but once the relation source entry is re-saved (either manually or via CLI), the described behaviour manifests.

I dumped the raw SQL from entry.entriesField.id(['not', 23432234]) before and after upgrading the site to 5.3.4 (and re-saving the entry) – here's a diff to highlight what changed (likely relevant, the INNER JOIN relations part is somehow gone): https://www.diffchecker.com/l25MWZtQ/ (the SQL from 5.2.10 is on the left; 5.3.4 on the right).

I'm able to reproduce this on a brand new 5.2.10 install after upgrading to 5.3.4; here's some steps for a reduced test case:

Steps to reproduce

  1. Install Craft 5.2.10
  2. Create a section and an entry type for that section
  3. Create an entries field with the handle entriesField, and add it to the entry type
  4. Create 3 entries in the section; "Entry 1", "Entry 2", "Entry 3"
  5. Add "Entry 2" to the entries field for "Entry 1"
  6. Add the following Twig to the entry template for the section, and visit "Entry 1"'s URL:
{% set entries = entry.entriesField.id(['not', 23432234]).all() %}

{% for entry in entries %}
    {{ entry.title }}<br/>
{% endfor %}

(The element ID in the .id(['not', ..) param is completely fictional, and it doesn't matter; the important thing is that the .id() param with the 'not' directive, is used).

As expected, the output should be

Entry 2<br/>
  1. Upgrade the site to Craft 5.3.4
  2. Reload "Entry 1"'s URL front end template and confirm that the Twig above still outputs the same result as before.
  3. Resave "Entry 1", either manually from the control panel or via the craft resave/entries CLI command
  4. Reload "Entry 1"'s URL front end template again, and confirm that the query now outputs the following:
Entry 1<br/>
Entry 2<br/>
Entry 3<br/>

Expected behavior

Adding .id(['not', id]) to an entry field query should return related entries excepting the one with the specified ID.

Actual behavior

After resaving the source entry in Craft 5.3.4, adding .id(['not', id]) to an entry query results in all entries except the excluded one being returned, regardless of the entry field's actual relations.

Similarly, adding .id(id) to the entry query results in the entry with the specified id being returned, even if it is not in fact related to the source entry in the entries field.

Craft CMS version

5.3.4

PHP version

8.2.20

Operating system and version

macOS, DDEV v1.23.3

Database type and version

Ver 8.0.36 for Linux on aarch64 (Source distribution)

Image driver and version

No response

Installed plugins and versions

None

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions