Skip to content

feat(lsp): add inlay hints and resolve hover through the catalog - #861

Open
psteinroe wants to merge 4 commits into
mainfrom
feat/inlay-hints
Open

psteinroe wants to merge 4 commits into
mainfrom
feat/inlay-hints

Conversation

@psteinroe

@psteinroe psteinroe commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Bring back parameter-name inlay hints, and make hover show what a name actually resolves to. Both are built on a new opt-in API on the catalog resolver that returns resolved references, not just errors.

Resolved references (pgls_catalog)

resolve can now also return what the names of a statement resolve to. This is enabled with ResolveParams::collect_references and returned in Resolution::references:

  • Function { function, arguments }: the overload a call resolves to via select_function, and which parameter each argument goes to.
  • Column { source, column }: source is a catalog relation, a CTE or a subquery alias. The column is recorded under its source's own name, even when an alias renames it. CTE and subquery columns carry their inferred type.
  • Relation { relation }: catalog relations in FROM and the targets of INSERT, UPDATE, DELETE and COPY.

Each reference has a location and span. A reference is only recorded when a name resolves to exactly one object. The linter passes false, so nothing is collected or allocated on its path, and a test checks that findings are identical either way. Explicit VARIADIC calls now go through overload resolution too, but are never reported. The Postgres regression suite passes, so typecheck findings are unchanged.

Inlay hints

A name: hint before positional function arguments when the call resolves to exactly one function:

select make_point(1, 2 + 3);      -- make_point(x: 1, y: 2 + 3)
select make_point(1, y => 2);     -- make_point(x: 1, y => 2)
select sum_all(1, 2, 3);          -- sum_all(base: 1, nums: 2, 3)

No hints for named arguments, unnamed parameters, arguments already named like the parameter, ambiguous or unknown calls, or SQL-syntax calls like EXTRACT. Adds the new pgls_inlay_hints crate, pull_inlay_hints in the workspace, and inlayHintProvider with a textDocument/inlayHint handler in the language server.

Hover

Hover resolves the innermost statement at the cursor with the file's DDL applied:

  • Functions: only the overload the call resolves to, instead of every overload with that name.
  • Columns: the column of the relation it actually comes from, through aliases and joins.
  • Relations: the table the search path picks.
  • CTE and subquery columns: a small new hover with their inferred type.

It falls back to today's name-based lookup when there is no unique reference. Hover now also works inside SQL function bodies. All existing hover snapshots are unchanged.

create function pick(i integer) returns integer ...;
create function pick(t text) returns text ...;
select pick(1);   -- hover: only `public.pick(i integer) → integer`

Risks and gaps

  • Hover and inlay hints walk the file up to the cursor or visible range and apply its DDL. This is shared in the new walk_statements helper. It's fine for typical files, but adds cost on very long ones.
  • walk_statements follows dbmate/goose migration sections like the analyser does. Each section gets its own session, and a down section sees the catalog after the up sections before it, without carrying its own DDL into the next section. Hover and inlay hints still work in down sections skipped with lintDown: false, because those sections are only excluded from linting.
  • No column references yet for INSERT column lists, UPDATE SET targets, excluded/old/new, NATURAL joins, or columns of functions in FROM. Hovering a table alias (u in u.name) still uses the name lookup.
  • CALL proc(...) gets no inlay hints, because the resolver doesn't handle CallStmt.

Fixes #130

@psteinroe
psteinroe added this pull request to stack #869 October 18, 2026 08:04
@psteinroe
psteinroe removed this pull request from stack #869 October 18, 2026 15:19
@psteinroe psteinroe changed the title feat(lsp): bring back inlay hints for function arguments feat(lsp): add inlay hints and resolve hover through the catalog Oct 18, 2026
Show the names of the parameters that positional function arguments are
passed to. The catalog resolver records the calls that overload
resolution selects exactly one function for, now also for explicit
VARIADIC calls, and the new pgls_inlay_hints crate turns them into hints.
The workspace exposes pull_inlay_hints, following the file's DDL like the
analyser, and the language server advertises inlayHintProvider.

Closes #130
Generalise the function call recording of the resolver into opt-in
references on Resolution: function calls, columns and relations that
resolve to exactly one object. Replaces resolve::function_calls; inlay
hints read the function references instead.
Hover resolves the statement at the cursor with the catalog the
analyser sees and shows the function overload, column, or relation the
hovered name resolves to. CTE and subquery columns show their inferred
type. Without a unique reference, hover falls back to the name lookups.
Hover now uses the innermost statement, so it also works inside SQL
function bodies.
Walk the statements like the analyser does since migration sections:
each section gets a session of its own, and a down section sees the
catalog after the up sections before it without carrying its own
changes into the next section.

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.

Bring back Inlay Hints

1 participant