Skip to content

docs: stop crediting SQLBaseProvider with placeholders - #650

Merged
cevheri merged 4 commits into
libredb:mainfrom
XiaoZ-0218:fix/docs-sqlbase-placeholder-attribution-647
Sep 8, 2026
Merged

docs: stop crediting SQLBaseProvider with placeholders#650
cevheri merged 4 commits into
libredb:mainfrom
XiaoZ-0218:fix/docs-sqlbase-placeholder-attribution-647

Conversation

@XiaoZ-0218

Copy link
Copy Markdown
Contributor

Follow-up to #642 / Fixes #647.

Keep the facts, drop the wrong SQLBaseProvider attribution for placeholders (four sites). Adds a citation-guard regression so the attribution cannot silently return.

@cevheri

cevheri commented Sep 8, 2026

Copy link
Copy Markdown
Member

Ran the new guard against main: 4 red, naming three of the four sites plus the heading. The control holds independently, sql-base.ts is 159 lines with eight members and zero /placeholder/imatches, and positionalPlaceholder() is values.ts:148. The surviving half of DATABASE_PROVIDERS.md:119 is true: none of ClickHouse, Druid or Trino declares escapeIdentifier() (ClickHouse only calls it, clickhouse/index.ts:1056).

One site is missing, and it is one my own issue undercounted. docs/providers/mysql.md:31 still reads "It extends the shared SQLBaseProvider (identifier quoting with backticks, automatic LIMIT injection, ? placeholders, cloud SSL auto-detection)". Same class as the four, same fix. I keyed #647's table on the phrasings I had already seen, which is exactly what #640's getPlaceholder grep did.

Four comments below. Three are the guard being narrower than the defect it exists to prevent, each with the probe that gets past it. The last is prose.

@cevheri

cevheri commented Sep 8, 2026

Copy link
Copy Markdown
Member

tests/unit/provider-docs-monitoring-citations.test.ts - PLACEHOLDER_CAPABILITY_SOURCE

This is a closed list of the four phrasings we already fixed, which is the shape of the defect rather than a guard against it. Probe: add "placeholder helpers" to postgres.md:42 beside "live in SQLBaseProvider" and the suite stays green (42 pass).

Replacing the source with String.raw\bplaceholders?\b`` leaves this PR green, so the breadth costs nothing here. Run that version over every file under docs/ and it finds `mysql.md:31`, plus one false positive worth designing around: `mssql.md:66` ("Bind placeholders are `@p1`, `@p2`") is a dialect fact that only trips because a link anchor two sentences earlier reads `#22-what-sqlbaseprovider-provides`.

tests/unit/provider-docs-monitoring-citations.test.ts - the denies clause

The ±220 character window means a denial anywhere nearby clears a real regression. Probe: append "SQLBaseProvider also handles placeholder generation for each dialect." directly after the "Not in the list ... no longer has one" sentence in DATABASE_PROVIDERS.md:119 and the suite stays green, with the broad regex too. That paragraph is exactly where such a regression would land, since it is where the denial now lives.

Scoping the window to the sentence containing the match instead of ±220 characters closes this, drops the mssql.md false positive above, and still catches mysql.md:31. One change, three problems.

tests/unit/provider-docs-monitoring-citations.test.ts - the ?? "(missing …)" fallback

A renamed heading turns this test into a pass rather than a failure. Probe: rename the section to "### What the SQL base class adds (SQL databases only)" and put positionalPlaceholder() back into its table. Green, with the regression in place. Assert the section was found before asserting what it contains.

docs/ADDING_A_PROVIDER.md:35

Dropping the count left the sentence without its noun: "It is sql-base.ts of pure SQL text helpers keyed off this.type". Something like "sql-base.ts is pure SQL text helpers keyed off this.type" reads, and keeps the link.

Two related things while you are here. DATABASE_PROVIDERS.md:119 borrows "Not in the list: a placeholder helper" into a paragraph that has no list, unlike clickhouse.md:126 where it follows one. And providers/postgres.md:83 still has the structure this PR just fixed here: the positionalPlaceholder() row sits under "### 2.2 What SQLBaseProvider provides", introduced by "inherits these from sql-base.ts rather than reimplementing them", with only the row's parenthetical contradicting the lead-in. mssql.md:66 links to that heading as the canonical list.
The new heading test covers ADDING_A_PROVIDER.md only.

@cevheri cevheri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch mysql.md:31 with a broad placeholders? regex and sentence-scoped
denial; hard-fail missing SQLBaseProvider sections; cover postgres
heading; fix ADDING_A_PROVIDER / DATABASE_PROVIDERS / postgres structure.
@XiaoZ-0218

Copy link
Copy Markdown
Contributor Author

Addressed the review:

  • Fixed mysql.md:31 (dropped ? placeholders from the SQLBaseProvider list)
  • Widened the guard to \bplaceholders?\b and scoped denial to the matching sentence (closes the ±220 probe; drops the mssql false positive)
  • Heading check hard-fails if the section is missing; also covers postgres §2.2
  • Prose: ADDING_A_PROVIDER.md noun fix, DATABASE_PROVIDERS.md paragraph-fitting denial, moved positionalPlaceholder() out from under postgres “What SQLBaseProvider provides”

@cevheri

cevheri commented Sep 8, 2026

Copy link
Copy Markdown
Member

All four closed. Re-ran the probes against 0509dcd7:

  • "placeholder helpers" credited in postgres.md — red
  • the regression in the sentence after the denial — red
  • the renamed heading with the row put back — red

The sentence scoping did both halves of its job: it catches the same-sentence attribution and it
drops the mssql.md:66 false positive, which is what makes the one-sentence reword of
DATABASE_PROVIDERS.md:119 the thing now carrying the denial. Local gates clean here: format,
typecheck, lint 0 errors.

One gap left, and it is the coverage half of my earlier comment rather than the breadth half. The
doc list is still four files, so a sixth site in an unlisted doc is invisible. Probe: add "It
extends the shared SQLBaseProvider (identifier quoting, ? placeholders, LIMIT injection)." to
sqlite.md and the suite is 44 pass. This file already has the idiom, PROVIDER_DOCS on line 48,
so [..., ...PROVIDER_DOCS] covers every provider doc. It is green: I ran the guard over every
.md under docs/, 127 pass, 0 fail.

that one line and I will merge.
thanks

@XiaoZ-0218

Copy link
Copy Markdown
Contributor Author

Coverage widened: PLACEHOLDER_ATTRIBUTION_DOCS is now [ADDING_A_PROVIDER, DATABASE_PROVIDERS, ...PROVIDER_DOCS] (d3252fc), so every doc under docs/providers/ is in scope. Local: guard file 60 pass 0 fail, format/typecheck/lint clean.

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@cevheri
cevheri merged commit 8079d8c into libredb:main Sep 8, 2026
22 checks passed
@cevheri

cevheri commented Sep 8, 2026

Copy link
Copy Markdown
Member

Confirmed. sqlite.md now goes red when a site is planted in it, naming the file and the sentence,
where it was invisible at 44 pass before. Guard file 60 pass, format/typecheck/lint clean here, and
all checks green on d3252fc.

Merging. One residual I will take myself in a follow-up rather than hold this: scope is
docs/providers/ plus the two top-level docs, so docs/ARCHITECTURE.md stays out, and it is the one
live doc besides these that names SQLBaseProvider. Nothing wrong there today. Running the guard
over every .md under docs/ is 127 pass, 0 fail, so it is a one-line widening and it was my
recommendation that scoped it narrower.

Good three rounds. The guard is now stronger than the defect it replaced, which is the part #647 was
actually about.

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.

docs: four sites credit SQLBaseProvider with placeholder generation it does not have

2 participants