ci(databases): run the suite on mysql and postgres - #4
Merged
Conversation
The README named MySQL and PostgreSQL as supported while the workflow installed sqlite and pdo_sqlite and nothing else, so no query had ever run against either. The two operators added for this release are the ones most likely to differ: contains_any and contains_all go through whereJsonContains, which the three drivers compile into json_each, json_contains and a jsonb containment, and the contains filter carries an explicit escape clause. A databases job runs the suite against MySQL 8.4 and PostgreSQL 17 as service containers. TestCase reads DB_DRIVER, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD and falls back to the in memory SQLite it used before, so nothing changes for a local run. Both operator families and the escape clause turned out to work on all three. Two real defects did not. Definitions came back in whatever order the database chose, so getCustomFields() and the generated filter and sort lists were ordered by insertion on SQLite and arbitrarily on a server, and the sort_order column that exists for this was never read. All three definition queries now order by sort_order and then by slug. A decimal value read back differently per driver. MySQL and PostgreSQL return the full scale of the decimal(20,6) column, so a stored 12.5 came back as 12.500000 while SQLite gave 12.5. DecimalType trims the fraction so the value the consumer wrote is the value it reads. The host tables the fixtures create are dropped on both ends of a test rather than only created, since a server keeps what the previous test left. The column type assertions accept the name each driver reports for a kind rather than the SQLite one. Verified locally against mysql:8.4 and postgres:17 in Docker: 115 tests pass on all three drivers.
composer test:unit runs Pest in parallel, and the two processes shared
the one database the service container provides, so they created and
dropped the same tables at the same time:
SQLSTATE[42S01]: Table 'custom_field_values' already exists
The job now calls Pest directly. Verified by reproducing the failure
with --parallel against mysql:8.4 and confirming the serial run passes.
That crash also exposed something worse: the interrupted run left its
tables behind, and every later run against the same server failed on a
schema it had never created. An in memory database starts empty each
time, a server does not. The test case now drops what a previous run
left before the migrator starts, so a server is usable again without
being recreated by hand. Verified by poisoning both a MySQL and a
PostgreSQL database with a crashed parallel run and watching the next
serial run come back green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The README named MySQL and PostgreSQL as supported while the workflow installed sqlite and pdo_sqlite and nothing else, so no query had ever run against either. The two operators added for this release are the ones most likely to differ: contains_any and contains_all go through whereJsonContains, which the three drivers compile into json_each, json_contains and a jsonb containment, and the contains filter carries an explicit escape clause.
A databases job runs the suite against MySQL 8.4 and PostgreSQL 17 as service containers. TestCase reads DB_DRIVER, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD and falls back to the in memory SQLite it used before, so nothing changes for a local run.
Both operator families and the escape clause turned out to work on all three. Two real defects did not.
Definitions came back in whatever order the database chose, so getCustomFields() and the generated filter and sort lists were ordered by insertion on SQLite and arbitrarily on a server, and the sort_order column that exists for this was never read. All three definition queries now order by sort_order and then by slug.
A decimal value read back differently per driver. MySQL and PostgreSQL return the full scale of the decimal(20,6) column, so a stored 12.5 came back as 12.500000 while SQLite gave 12.5. DecimalType trims the fraction so the value the consumer wrote is the value it reads.
The host tables the fixtures create are dropped on both ends of a test rather than only created, since a server keeps what the previous test left. The column type assertions accept the name each driver reports for a kind rather than the SQLite one.
Verified locally against mysql:8.4 and postgres:17 in Docker: 115 tests pass on all three drivers.