Skip to content

[6.x] Match entries with an unset field when querying with a not equals operator - #605

Draft
lazerg wants to merge 2 commits into
statamic:5.xfrom
lazerg:fix/issue-603-unset-field-queries
Draft

[6.x] Match entries with an unset field when querying with a not equals operator#605
lazerg wants to merge 2 commits into
statamic:5.xfrom
lazerg:fix/issue-603-unset-field-queries

Conversation

@lazerg

@lazerg lazerg commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

When a blueprint field has never been set on an entry, its key is simply missing from the data column, so json_extract returns NULL and where('archived', '!=', true) skips the entry. The Stache matches it. A template like {{ collection:things archived:isnt="true" }} therefore lists everything on the file driver and nothing here.

I've deliberately kept this much narrower than the change suggested in the issue. It only applies to != and <>, and only to a top level field key in the data column. Real columns are left alone, so where('date', '!=', ...) still follows normal SQL null rules. Nested paths are untouched too, so where('content->value', '<>', 1) still ignores entries whose content isn't shaped that way, as entries_are_found_using_where_with_json_value expects. No existing test needed changing.

Fixes #603.

@ryanmitchell

Copy link
Copy Markdown
Contributor

As I said in the issue, I'm still not convinced this is necessary. With eloquent you can make a migration to backfill the data, and most developers using eloquent driver would understand and expect to do that.

This PR basically forces a whereNull check for any field you query, which is not necessaroly what you would want if you are doing direct queries.

Happy to be overruled @duncanmcclean

@lazerg

lazerg commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

One clarification on the scope, since "any field you query" is broader than what this actually does.

The rewrite only applies to != and <>, and only when the column resolves to a top level key in the data array. Real database columns never reach it, so direct queries against those keep normal SQL null behaviour. Nested paths don't reach it either, so your content->value test from 2022 is unchanged and still passes. The test file is additions only.

The rest is your call, I'm happy either way.

@ryanmitchell

ryanmitchell commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Yes I understand the scope.

However it would mean if I run $query->where('my_field', '<>', 1) it will now actually run $query->where('my_field', '<>', 1)->orWhereNull('my_field') which I don't think its correct, even if it matches the stache.

@ryanmitchell

Copy link
Copy Markdown
Contributor

Chatted with Duncan off-thread on this and as its a breaking change we'll target the next major version with this and document it in the upgrade guide.

@ryanmitchell
ryanmitchell marked this pull request as draft August 11, 2026 08:20
@ryanmitchell ryanmitchell changed the title Match entries with an unset field when querying with a not equals operator [6.x] Match entries with an unset field when querying with a not equals operator Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Entries with an unset field are matched by the Stache but not by the eloquent driver

2 participants