ci: run the suite against PostgreSQL, and fix what that found - #105
Merged
Conversation
DATABASE_URL has been the design since ADR 0003 and no job had ever run a line of the suite on PostgreSQL, so F-6.3's claim of adapter parity rested on the adapter that hides the difference. The first run failed 310 of 393 examples and not one was application code: a spec hook issued PRAGMA case_sensitive_like, which PostgreSQL rejects as a syntax error, and a rejected statement there aborts the whole transaction — so one adapter-blind hook failed nearly everything after it. The hook now asks the adapter first. Both adapters run the same 393 examples green. The job loads the schema rather than db:prepare, which seeds a database it creates, and seeded rows survive the per-example transaction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDUtHLJxUmEKXVbBJmcbAh
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.
DATABASE_URLhas been the design since the beginning,docs/database.mdsays the switch is one environment variable, and no job had ever run a line of the suite on PostgreSQL. F-6.3 — "search behaves identically on SQLite and PostgreSQL" — rested on the adapter that hides the difference.So I ran it.
The first run failed 310 of 393 examples
And not one of them was application code.
A spec hook issued
PRAGMA case_sensitive_like = ON— SQLite's way of makingLIKEcase-sensitive, which is what let #97's specs reproduce the PostgreSQL behaviour before the switch. On PostgreSQL that's a syntax error, and in PostgreSQL a failed statement aborts the entire transaction. So one adapter-blind hook didn't fail one example; it failed nearly everything that ran after it.The hook now asks the adapter first. Both adapters run the same 393 examples, green.
That's the finding worth keeping: the app was portable and the test suite wasn't — and that's exactly the sort of thing that stays invisible until something actually runs it. The same shape as the
libvipsgap in #100, where the weak assertion existed because CI couldn't do better.What the job proves that nothing did before
LOWER(…) LIKE … ESCAPEworks on bothDATABASE_URLswitch worksPost.search's case folding and theESCAPEclause from #97 both hold up on the adapter they were written for — which is the first time that's been more than an argument.Two decisions in the job
db:schema:load, notdb:prepare.db:prepareseeds a database it creates, and seeded rows aren't rolled back by the per-example transaction, so every expectation about which posts exist fails. That cost me two debugging rounds locally — the comment in the workflow says so, so it costs no one else.Verified locally against a real PostgreSQL 16 before writing the workflow: 393 green on PostgreSQL, 393 green on SQLite, RuboCop clean.
F-6.3 no longer says "still unproven against a real PostgreSQL", because it no longer is.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KDUtHLJxUmEKXVbBJmcbAh
Generated by Claude Code