8000 feat(engine): show column comments in the row's hover by colinhacks · Pull Request #35 · colinhacks/reylo · GitHub
[go: up one dir, main page]

Skip to content

feat(engine): show column comments in the row's hover - #35

Merged
colinhacks merged 5 commits into
mainfrom
column-comments
Oct 22, 2026
Merged

colinhacks merged 5 commits into
mainfrom
column-comments

Conversation

@colinhacks
@colinhacks colinhacks commented Oct 22, 2026 •
Copy link
Copy Markdown
Owner

Postgres and MySQL let a schema document a column (COMMENT ON COLUMN users.age IS 'Age (in years)', age int COMMENT 'Age (in years)'). Reylo now reads those comments and prints each one as the doc comment of every Row field that reads the column as it is, so the editor's hover over user.age shows "Age (in years)". SQLite keeps no comments, so nothing changes there.

Before / after

create table users (id int primary key, age int, email text not null);
comment on column users.age is 'Age (in years)';
comment on column users.email is E'Where we write to them.\nNever shown to other users.';

select id, age, age as years, email, lower(email) as lower_email from users where id = :id

Before:

export type Row = { id: number; age: number | null; years: number | null; email: string; lower_email: string };

After:

export type Row = {
  id: number;
  /** Age (in years) */
  age: number | null;
  /** Age (in years) */
  years: number | null;
  /**
   * Where we write to them.
   * Never shown to other users.
   */
  email: string;
  lower_email: string;
};

A type with no comments is still written on one line, exactly as before. With a comment, each field gets a line of its own, because TypeScript 7's language server reads a JSDoc only where a line starts with it: { id: number; /** doc */ age: number } shows no documentation in the hover, and the same type with a line break before /** does.

The language server's hover over user?.age (from the new test):

```typescript
(property) age: number | null | undefined
```
Age (in years)

What changed

  • Engine (Column, Param): each gets an optional comment field, which is left out of the JSON when there is none.
  • Postgres: a new catalog query, COMMENTS_QUERY (pg_description by table oid and attnum), is asked in the same round as the CHECKs, for each result column whose origin the describe names. So an alias keeps its column's comment, and an expression has none. A column whose provenance names only a set operation's leftmost arm (own_provenance) gets no comment. Read through a view, a column takes the view's own column comment, or, where the view's column has none, the comment of the column the view's definition reads. A parameter written to a column (an insert's value, set age = :age) carries that column's comment. A parameter compared with a column does not, because the Postgres engine doesn't track which column a comparison reads.
  • MySQL: the existing information_schema.columns query for parameter types (TYPES_QUERY) now also reads column_comment, and is asked in the prepare's round for the tables a parameter is written to or compared with, plus the tables of a plain SELECT's FROM. A result column takes the comment of its org_table / org_name only when the SELECT reads no WITH query or derived table. Through those, MySQL names the base table beside the derived column's own name (select doc from (select other as doc from o) s reports o.doc), which can be another column of that table. An empty comment counts as none. A parameter written to or compared with a column carries that column's comment.
  • Mapper (src/module-types.ts): prints the comments on Row and Params fields, writing a multi-line comment as a block through src/doc-comment.ts, which also escapes */ as *\/.
  • Schema fingerprint (src/analyze.ts): covers column comments on both databases, so an edited comment re-types the import instead of the .reylo/ entry being kept.
  • Docs: one sentence in the Inference section saying that the editor shows a column's comment on hover.

Verified

  • Engine unit tests: Postgres (an alias, an expression, a view's own comment and the fallback to its base column, a set operation, a written parameter) and MySQL (an alias, an expression, a compared parameter, a derived table).
  • tests/comments.test.ts against throwaway Postgres 18 and MySQL 8.4, through the content mapper's JSON-RPC process: the exact Row and Params text, multi-line comments, the */ escape, a view, a derived table, and a changed comment re-typing the import from a new process. Run without the fingerprint change, this test fails on the stale .reylo/ entry. A language-server hover test checks that the comment shows over a field of the query's row.
  • No oracle expected.txt changed: the oracle prints its own form of the analysis.
  • Gates: cargo-build, engine-tests, oracle-tests, wasm, oracle, typecheck, loader-tests (0 skipped), package and site all pass.

Copilot AI balanced review requested due to automatic review settings October 22, 2026 21:14
@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 10:44pm UTC

Request Review

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.

ℹ️ No critical issues — one edge case inline.

Reviewed changes

I reviewed the whole PR: reading column comments on Postgres and MySQL and printing them as JSDoc on Row/Params fields.

  • Engine API: Column and Param gain an optional comment, which is left out of the JSON when there is none. SQLite always leaves it as None.
  • Postgres: a new COMMENTS_QUERY is asked in the same round as the CHECKs. Engine::comments gates result columns on own_provenance, follows a view's column to its source column, and gives a written parameter its column's comment when all the columns it fills share one.
  • MySQL: column_types becomes typed and returns Typed { types, comments, columns }, and TYPES_QUERY now reads column_comment. The tables come from both the parameters' targets and traced_from, so a result column gets a comment only for a plain SELECT whose org_table is one of its FROM tables.
  • Mapper: fieldComment/objectType in src/module-types.ts keep a type on one line when no field has a comment. Otherwise each field gets its own line after its doc comment. Only src/mapper.ts calls moduleTypes. The site's capture-types.ts renders its own one-line types, so the site regexes that parse export type Row = (.*); are unaffected.
  • Fingerprint: src/analyze.ts now includes pg_description column comments and MySQL's md5(column_comment), so an edited comment re-types the import.

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

Comment thread engine/postgres/src/postgres.rs Resolved
@colinhacks
colinhacks force-pushed the column-comments branch 2 times, most recently from 6f7e45f to 04024c7 Compare October 22, 2026 22:14
@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 set-operation fix closes the earlier finding.

Reviewed changes

I reviewed ca02082, the one commit since the last Pullfrog review.

  • Per-position result comments: Engine::comments now returns Comments { columns, written }. columns holds one entry per result column and is None wherever own_provenance is false, so run() no longer looks up a set-operation column by its leftmost arm's (table, attnum). The empty-pairs path fills columns with None too.
  • Parameter comments: the (relation, attnum) map is now used only for written parameters (comments.written). It is built from the same by_column resolution, so view-to-source fallback still applies.
  • Test: added the CTE-union case. a.id gets no comment and u.id AS uid keeps its own. cargo test -p reylo-engine-postgres --lib comment and tests/fingerprint.test.ts pass locally.

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

@colinhacks
colinhacks merged commit d8d276c into main Oct 22, 2026
6 checks passed
@colinhacks
colinhacks deleted the column-comments branch October 22, 2026 22:49
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

0