Skip to content

h5i-app-pg: refuse mixed-case schema names in with_schema - #765

Open
hiroki-abe-58 wants to merge 1 commit into
h5i-dev:mainfrom
hiroki-abe-58:fix/with-schema-lowercase
Open

hiroki-abe-58 wants to merge 1 commit into
h5i-dev:mainfrom
hiroki-abe-58:fix/with-schema-lowercase

Conversation

@hiroki-abe-58

Copy link
Copy Markdown

What. with_schema now refuses schema names containing anything other than [a-z0-9_]; before, it accepted any [A-Za-z0-9_]+. There is one check with one error message, and three unit tests.

Why. with_schema puts the name into search_path unquoted, and PostgreSQL folds it to lowercase. install_schema reads current_setting('search_path') and runs CREATE SCHEMA IF NOT EXISTS "<name>", quoted and as written.

With with_schema(url, "Board"):

  1. install_schema creates the schema "Board".
  2. The search path names board, which doesn't exist.
  3. The first unqualified CREATE TABLE fails with 3F000: no schema has been selected to create in.

Every caller in the repository already uses a lowercase name, so with_schema now refuses names it cannot install, instead of letting install_schema fail later. I did not fold the name to lowercase, because "Board" and "board" would then silently share a schema. I did not quote it in search_path either, because that would change every existing caller's URL and introduce case-sensitive schema names.

Behavior change. A name with uppercase letters now fails in with_schema instead of in install_schema.

One setup used to work by accident. If a lowercase schema such as board already existed, install_schema succeeded, put the tables in board, and left an empty "Board" schema behind. That setup now gets an error and must use the lowercase name.

install_schema still reads an unquoted mixed-case search path that is set by other means (raw options=, ALTER ROLE ... SET search_path) the same way as before. I can also fold unquoted names there, if you prefer.

Reproduction (PostgreSQL 17).

  • On f88e995, build an Engine on pool(&with_schema(url, "Board")?, ..) and call install_schema(). It fails with 3F000: no schema has been selected to create in, and current_schema() is NULL. With "board" it succeeds.
  • On this branch, with_schema(url, "Board") returns Err(Decode("schema name \"Board\" must be [a-z0-9_]+")).

Tests

  • cargo test --locked -p h5i-app-pg, with and without --all-features, run against a local PostgreSQL 17 through H5I_APP_TEST_DATABASE_URL: 8 passed, 0 skipped. That includes the 3 reads_test DB tests.
  • cargo clippy --locked -p h5i-app-pg --all-targets --all-features -- -D warnings: clean.
  • With only the new tests added on main, with_schema_refuses_names_postgres_would_fold fails on "Board".
  • Not run: the workspace-wide checks, the examples workspace (its callers all use lowercase literals), and the cargo app checks. No proof or trust assumption changes.

This change was written with Claude Code (Claude Opus 5.5). It has been reviewed only by AI, in a separate session; no human has reviewed it.

🤖 Generated with Claude Code

`with_schema` puts the name into `search_path` unquoted, where PostgreSQL
folds it to lowercase, but `install_schema` creates the schema quoted, as
written. With `with_schema(url, "Board")`, `install_schema` creates "Board",
the search path names `board`, and the next CREATE TABLE fails with
"no schema has been selected to create in". Refuse names with uppercase
letters up front; every caller in the repository already uses lowercase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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