Skip to content

feat: end each statement with a comment naming its file - #43

Merged
colinhacks merged 1 commit into
mainfrom
query-comment
Oct 22, 2026
Merged

colinhacks merged 1 commit into
mainfrom
query-comment

Conversation

@colinhacks

@colinhacks colinhacks commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Every statement a build step writes now ends with a comment naming its .sql file, in sqlcommenter's format. It's always on, with no setting:

select id, name, email from users where id = $1::int /*file='queries%2Fget_user.sql'*/

Database monitoring that reads sqlcommenter tags (Datadog Database Monitoring, PlanetScale's query insights) then groups statements by file with no hook in the app, and pg_stat_activity and slow-query logs show it as written. Cloud SQL Query Insights keeps only its six fixed tag names, so it ignores file.

  • The comment (src/sqlcommenter.ts): at the end of the statement and before a closing semicolon. The path is URL-encoded, and a quote is escaped as the spec writes a value. After a line comment (--, or MySQL's #) it starts a line of its own, so the line comment cannot swallow it. The file is its one tag, so the text is the same on every call and a driver's statement cache keeps it. URL encoding leaves no ?, : or $ in it, so no driver reads a placeholder there.
  • Where: the build steps' module (sql, which .run() sends) and the type check's declaration of sql carry the same text. The path is the query's .source, computed from the file's own project in both (sourceName in src/project.ts). A query defined by hand has none.
  • Hovers: the sql doc comment shows the statement without the comment, since a doc comment cannot hold its */. The type itself shows the full text, and the note now says a comment naming the file ends it.
  • Docs: a sentence under Usage's .sql, and the captured hover types regenerated (nub run capture).

Test plan

  • nub run typecheck
  • nub run test against throwaway Postgres 18 and MySQL 8.4: 207 pass. The one failure, "SQLite: JSON a statement builds is the object its type says…", fails the same way on main under Node 26.11: its node:sqlite runs SQLite 3.54.1, which drops a nested json_group_array's JSON subtype. CI's Node 24 is unaffected; that bug gets its own PR.
  • tests/sqlcommenter.test.ts: placement (plain, trailing newline, semicolon, a line comment, MySQL's #), encoding and escaping; every form prepared and run on SQLite
  • Every built module's sql, its declaration and the editor hover (tests/compiled.test.ts, tests/analyze.test.ts, tests/definition.test.ts). The cast tests check the comment once in their helper and compare the cast text without it.
  • site: nub run capture, nub run build; the .sql section checked at desktop and phone widths

@vercel

vercel Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
reylo Ready Ready Preview Oct 22, 2026 11:19pm UTC

Request Review

Copilot AI balanced review requested due to automatic review settings October 22, 2026 22:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Two things to fix before merge. In a running dev server, turning sqlcommenter on or off doesn't reach the build until a restart. The docs also say Cloud SQL Query Insights reads the file tag, but it drops that key.

Reviewed changes

I reviewed the opt-in sqlcommenter key end to end: the engine config, the comment builder, the build-step module, the type check's declaration and the docs.

  • Config key: sqlcommenter: Option<bool> on the engine's Project, with all three engine.wasm files rebuilt. resolveProject defaults it to false.
  • withSqlcommenter: adds /*file='…'*/ before any closing semicolon. After a -- or # on the last line, the tag goes on a new line. encodeURIComponent encodes /, ?, : and $, so the tag can't contain */ or a placeholder. tests/sqlcommenter.test.ts passes locally.
  • sourceName: the query's source now comes from the file's own project. This matches the old relative(session.project.root, path), because Session.for resolves from packageDir(dirname(path)) too.
  • Loader and mapper: the module's sql/text and the declared sql literal both carry the tag. Structured-list offsets are still correct, because the tag only adds text at the end. The mapper's configIdentity includes the new flag.
  • Docs: the key is in the Configuration example and has its own section.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread src/loader.ts Resolved
Comment thread src/sqlcommenter.ts Resolved
Comment thread src/loader.ts Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found. Both must-fix items and the nit from the previous review are fixed.

Reviewed changes

This run covered 7ca1cdd, the one commit pushed since the previous review.

  • Session cache key: Session.for now adds project.sqlcommenter to its cache key. If the project file turns the key on or off, the next module gets a new session, so the module's sql matches what the mapper declares. A session left behind this way closes its connection after BUILD_IDLE, the same as when url changes today.
  • Test: tests/compiled.test.ts no longer closes sessions before the second build. It now tests the real case: a running build step picking up the change without a restart.
  • Docs and comments: removed the Cloud SQL Query Insights claim from the Configuration section and the src/sqlcommenter.ts header.
  • Loader: moved the structured-offsets comment back above the structured line.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

Every statement a build step writes ends with /*file='queries%2Fget_user.sql'*/
in sqlcommenter's format, so database monitoring that reads it groups
statements by file. The sql doc comment shows the statement without it.
@colinhacks colinhacks changed the title feat: tag each statement with its file in a sqlcommenter comment feat: end each statement with a comment naming its file Oct 22, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found. The branch was squashed and reworked so the comment is always on; I re-read the full diff.

Reviewed changes

The force-push to d991d85 removed the opt-in setting. Every built statement now gets the comment.

  • Removed the sqlcommenter key: the engine config change, the rebuilt engine.wasm files, the Session.for cache-key change and the Configuration docs section are all gone. With no setting, a running build and the type check can't disagree about whether the comment is there.
  • Kept withSqlcommenter as it was: trailing whitespace and ; are trimmed, the tag goes before a closing ;, and after a -- or # on the last line it starts a new line. The compiled text no longer ends with a newline, and the tests now expect that. tests/sqlcommenter.test.ts passes locally on Node 24.
  • Made the declared sql match the module: the mapper now computes sourceName(p.fileName) from the file's own project, the same way the loader does. The sql doc comment shows the text without the tag, since a doc comment can't contain */. source is still typed as string.
  • Updated the docs capture: site/scripts/capture-types.ts follows the mapper, using the block's name as the source, and sql-modules.json was recaptured. 02-usage.mdx gained one sentence and SQL_NOTE now mentions the ending comment.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@colinhacks
colinhacks merged commit bc71385 into main Oct 22, 2026
6 checks passed
@colinhacks
colinhacks deleted the query-comment branch October 22, 2026 23:29
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.

2 participants