Winter CMS Build
wip/1.3
PHP Version
8.4
Database engine
MySQL/MariaDB
Plugins installed
No response
Issue description
On the Laravel 12-compatible wip/1.3 branch, exact-mode backend list search can fail when the searched column is generated from a relation field and is represented as an Illuminate\Contracts\Database\Query\Expression instead of a plain string column name.
This commonly happens in backend controllers where a parent model list shows values from related records using type: relation in columns.yaml.
The same code path existed in v1.2.12, but it did not fail in my older installation because that branch runs against Laravel 9, where query Expression objects could still be implicitly converted to strings. In Laravel 12, expressions need to be resolved with the active query grammar via getValue($grammar).
Context
In src/Database/Builder.php, searchWhereInternal() already handles Expression values in the non-exact search path by resolving the expression through the query grammar.
However, the exact branch does not do the same. It passes $field directly into DbDongle::cast() / sprintf():
$fieldSql = $this->query->raw(sprintf("lower(%s)", DbDongle::cast($field, 'text')));
When $field is an Expression, this can fail on Laravel 12 because the object is not safely string-castable.
Why this may not fail on v1.2.12
This issue can be confusing because the same columns.yaml and model definition may work correctly on v1.2.12 but fail on wip/1.3.
The reason appears to be the Laravel framework version difference:
v1.2.12 requires Laravel 9.
wip/1.3 requires Laravel 12.
Laravel 9 still allowed Expression to be implicitly converted to a string in this context.
Laravel 12 expects expression values to be resolved using the database grammar.
So this is best understood as a Laravel 12 compatibility issue in the exact-search branch, rather than necessarily a visible bug in a standard v1.2.12 installation.
Expected behavior
Exact search should support expression-backed columns in the same way that the non-exact search path already does.
Searching a relation-backed list column should not fail when the resolved searchable column is an Expression.
Actual behavior
Exact search can fail when $field is an Expression, because the exact search path does not resolve it through the current query grammar before building the lower(...) LIKE ... SQL fragment.
Steps to replicate
- Create a model that has a many-to-many relationship and a list controller for the model that shows the related model
- In Laravel 9 / Winter 1.2.x it works, in wip/1.3 it fails when running a search.
Workaround
No response
Winter CMS Build
wip/1.3
PHP Version
8.4
Database engine
MySQL/MariaDB
Plugins installed
No response
Issue description
On the Laravel 12-compatible wip/1.3 branch, exact-mode backend list search can fail when the searched column is generated from a relation field and is represented as an Illuminate\Contracts\Database\Query\Expression instead of a plain string column name.
This commonly happens in backend controllers where a parent model list shows values from related records using type: relation in columns.yaml.
The same code path existed in v1.2.12, but it did not fail in my older installation because that branch runs against Laravel 9, where query Expression objects could still be implicitly converted to strings. In Laravel 12, expressions need to be resolved with the active query grammar via getValue($grammar).
Context
In src/Database/Builder.php, searchWhereInternal() already handles Expression values in the non-exact search path by resolving the expression through the query grammar.
However, the exact branch does not do the same. It passes $field directly into DbDongle::cast() / sprintf():
$fieldSql = $this->query->raw(sprintf("lower(%s)", DbDongle::cast($field, 'text')));
When $field is an Expression, this can fail on Laravel 12 because the object is not safely string-castable.
Why this may not fail on v1.2.12
This issue can be confusing because the same columns.yaml and model definition may work correctly on v1.2.12 but fail on wip/1.3.
The reason appears to be the Laravel framework version difference:
v1.2.12 requires Laravel 9.
wip/1.3 requires Laravel 12.
Laravel 9 still allowed Expression to be implicitly converted to a string in this context.
Laravel 12 expects expression values to be resolved using the database grammar.
So this is best understood as a Laravel 12 compatibility issue in the exact-search branch, rather than necessarily a visible bug in a standard v1.2.12 installation.
Expected behavior
Exact search should support expression-backed columns in the same way that the non-exact search path already does.
Searching a relation-backed list column should not fail when the resolved searchable column is an Expression.
Actual behavior
Exact search can fail when $field is an Expression, because the exact search path does not resolve it through the current query grammar before building the lower(...) LIKE ... SQL fragment.
Steps to replicate
Workaround
No response