Skip to content

Test identifier handling against real engines and hostile schemas - #27

Merged
rahulmahadik merged 2 commits into
mainfrom
develop
Aug 14, 2026
Merged

rahulmahadik merged 2 commits into
mainfrom
develop

Conversation

@rahulmahadik

Copy link
Copy Markdown
Owner

A mixed-case Postgres schema failed every query and shipped that way for weeks. The reason is structural: nothing in CI had ever pointed at a schema we did not write ourselves, so every database test shared the same blind spots by construction.

pnpm test:schemas runs the normalise-then-guard path against Postgres, MySQL and SQLite over schemas built to break the rules: mixed case, reserved words, spaces and symbols, unicode, and names the SQL parser treats as keywords.

No model is involved. This class of defect does not need one to surface, and a model would only make the result non-deterministic.

What keeps it honest

  • On an engine that folds unquoted names, each fixture first asserts the bare form genuinely fails. A fixture that would pass without the fix is reported as testing nothing, rather than counted as a pass.
  • An unreachable engine is skipped, never passed. CI passes --require=postgres,mysql,sqlite, so the job cannot go green on the embedded engine alone when the service containers fail to start.

Verified against itself

Removing the normalisation makes three fixtures fail with the error users actually saw:

FAILED postgres / mixed case [bare]: relation "customers" does not exist

Restored: 26 passed, 0 failed, 0 skipped across the three engines.

Adds a schema-regression CI job with Postgres and MySQL services, and documents the gate in CONTRIBUTING.

A mixed-case Postgres schema failed every query and shipped that way for weeks.
Nothing in CI had ever pointed at a schema we did not write ourselves, so every
database test shared the same blind spots.

This runs the normalise-then-guard path against Postgres, MySQL and SQLite over
schemas built to break the rules: mixed case, reserved words, spaces, unicode,
names the parser treats as keywords. No model is involved; it is not needed to
surface this class of defect and would only make the result non-deterministic.

Two rules keep it from going quiet. On a folding engine each fixture first
asserts the bare form genuinely fails, so a fixture that would pass without the
fix is reported as testing nothing. An engine that cannot be reached is skipped
rather than passed, and CI names the engines it requires so the job cannot go
green on the embedded one alone.

Removing the normalisation makes three fixtures fail with the error users saw:
relation "customers" does not exist.
@rahulmahadik
rahulmahadik merged commit f00539b into main Aug 14, 2026
10 checks passed
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.

1 participant