Use whereLike for search so MySQL works alongside PostgreSQL - #302
Conversation
Seven search call sites used the `ilike` operator, which only PostgreSQL understands. On MySQL they raise a syntax error, so post, asset, label, signature and workspace-member search — plus the MCP list-posts tool — were unusable on an engine `config/database.php` has always supported and the docs advertise. Replace them with `whereLike($column, $value)`, which the query grammars translate per driver: PostgresGrammar emits `ilike` and MySqlGrammar emits `like`. The generated SQL on PostgreSQL is therefore unchanged. Verified by running the full suite on both engines: PostgreSQL 16 3888 passed, 0 failed MySQL 8.0.46 one pre-existing failure fixed, none introduced Also adds case-insensitivity assertions to the five affected suites that lacked them, and search coverage for ListPostsTool, which had none. Note for MySQL installs: `like` is case-insensitive by virtue of the column collation, not the operator. Under the default `utf8mb4_unicode_ci` it is also accent-insensitive, so a search for "cafe" matches a stored "café" — PostgreSQL's `ilike` does not. That difference comes from the collation rather than this change. A `_bin` or `_cs` collation would make search case-sensitive on both.
|
Thank you @jonto , reviewing it! |
|
Thanks for this, Jamie — really solid contribution. I'm approving it. I went through it carefully on my side. All seven On the MySQL side not being fully there yet — you listed the remaining failures (the FK-backed index drop, JSON key ordering, If it's easier to split, a first PR with just the MySQL job in the workflow would already be valuable on its own, and the individual test fixes could follow after. Thanks again for taking the time to dig into this. |
|
Thanks Paulo — and thanks for reviewing it that carefully. Your point about the tests is fair and I should have caught it: the assertions I added run only on PostgreSQL, where One wrinkle worth deciding together before I open anything. The MySQL job on its own would land red, because the 32 remaining failures are already there and none of them are about search:
So "workflow job first, fixes after" would put a failing job on
I'd suggest (1), but it's your repo and your CI, so tell me which you'd prefer and I'll follow it. Either way the fixes are all confined to For context on how the number was established: I ran the full suite on both engines, PostgreSQL 16 green at 3888, MySQL 8.0.46 at 3856/32, and used the green PostgreSQL run to confirm every one of the 32 is a genuine engine Separately, and at your discretion — while testing the queue on MySQL I hit something that affects any self-hoster who sets |
|
Thanks for laying it out that clearly, Jamie. The breakdown of the 32 made this an easy call. Please go ahead and open a separate PR that fixes all of it, so MySQL ends up fully supported. Whether that lands as one PR or split by class is your call — you have a better sense of the shape of the work than I do, and you already offered to start with the 18, which sounds right. If you want to add a MySQL leg to CI as part of that, very welcome too. I'll leave the sequencing to you. Your And yes, please open the issue for the Thanks again for sticking with this. |
The problem
Seven search call sites use the
ilikeoperator, which only PostgreSQLunderstands. On MySQL they raise a syntax error, so post search, asset
search, label and signature search, workspace-member search, and the MCP
list-poststool are all unusable — on an engineconfig/database.phphas always carried a complete connection block for, and that the
self-hosting docs advertise as supported.
The change
Replace them with
whereLike($column, $value). The query grammarstranslate it per driver:
PostgresGrammar::whereLike→ilikeMySqlGrammar::whereLike→likeThe SQL generated on PostgreSQL is therefore unchanged — this is a
no-op for existing installs.
Verification
Full suite on both engines with the patch applied:
The remaining MySQL failures are unrelated to search and pre-date this
change (test-only: an FK-backed index drop, JSON key ordering,
tinyint(1)vsboolean, a 2099 date sentinel, and aDB::listenpredicate that hardcodes Postgres identifier quoting). Happy to open a
follow-up if a MySQL CI leg would be welcome.
Tests
Adds case-insensitivity assertions to the five affected suites that
lacked them, and search coverage for
ListPostsTool, which had none.Note for MySQL installs
likeis case-insensitive by virtue of the column collation, not theoperator. Under the default
utf8mb4_unicode_ciit is alsoaccent-insensitive, so searching
cafematches a storedcafé—PostgreSQL's
ilikedoes not. That comes from the collation rather thanthis change. A
_binor_cscollation would make searchcase-sensitive on both engines.