Skip to content

feat: unqualified column completion inferred from the FROM clause#165

Merged
mscolnick merged 4 commits into
mainfrom
ms/infer-columns-from-from-clause
Jul 23, 2026
Merged

feat: unqualified column completion inferred from the FROM clause#165
mscolnick merged 4 commits into
mainfrom
ms/infer-columns-from-from-clause

Conversation

@mscolnick

@mscolnick mscolnick commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Typing a bare identifier prefix now completes columns of the tables referenced in the current statement's FROM/JOIN clauses — even when the schema defines many tables:

SELECT id, name, email
FROM users
WHERE active = true
ORDER BY created_at DESC;

SELECT eemail, ORDER BY crecreated_at, because FROM users is in the statement.

Previously unqualified column completion was delegated entirely to @codemirror/lang-sql's schemaCompletionSource, which only offers top-level columns when a single defaultTable is configured — impossible with 2+ tables/schemas.

Changes

  • New unqualifiedColumnCompletionSource({ schema?, parser?, contextAnalyzer? }) (src/sql/column-completion-source.ts):
    • Matches bare identifier prefixes; skips qualified paths (after a dot — the alias source's territory) and table-name positions (right after FROM/JOIN/INTO/UPDATE/TABLE)
    • Scopes to the statement under the cursor; reuses QueryContextAnalyzer (AST walk + regex fallback, so it works mid-edit on unparsable SQL)
    • Offers the union of all FROM/JOIN tables' columns with detail: "column of <table>"; duplicate names across joins appear once
    • CTEs in FROM resolve to their declared/inferred columns; under-qualified tables that are ambiguous across schemas yield nothing rather than wrong columns
    • Empty prefix completes only on explicit (Ctrl-Space) requests; columns get a small boost to rank just above keywords
  • src/sql/completion-utils.ts: resolveSchema / findTableColumns / toCompletion lifted unchanged from the alias source and shared by both (no behavior change to aliasColumnCompletionSource)
  • Exported from src/index.ts, registered in the demo (sharing one QueryContextAnalyzer across completion sources), documented in README

Test plan

  • 18 new tests in src/sql/__tests__/column-completion-source.test.ts: the motivating multi-table scenario, ORDER BY, joins + per-table details, dedup, dot/table-position guards, empty prefix, mid-edit SQL, multi-statement scoping, aliased/quoted/nested tables, ambiguity, CTEs, facet fallback, boosts
  • pnpm test (412 passed), pnpm run typecheck, pnpm exec oxlint, pnpm run demo all clean

Summary by cubic

Adds FROM-aware autocomplete for bare column prefixes. Typing unqualified text like SELECT e now suggests columns from tables in the current statement, including joins and CTEs, with better multi‑schema support than @codemirror/lang-sql.

  • New Features

    • Add unqualifiedColumnCompletionSource({ schema?, parser?, contextAnalyzer? }).
    • Completes in SELECT/WHERE/ORDER BY; skips after a dot and in table-name positions; empty prefix only on explicit request.
    • Unions columns from FROM/JOIN tables; de-dupes; shows "column of "; supports CTE columns; small boost over keywords; falls back to sqlSchemaFacet; preserves schema-provided boosts.
    • Bug Fixes

      • No suggestions inside string literals or comments.
      • Skip in comma-continued FROM table lists; still completes after commas in SELECT/GROUP BY.
      • Correctly resolves quoted table names containing dots (e.g. "my.table").
    • Written for commit 6510749. Summary will update on new commits.

      Review in cubic

Typing a bare prefix (SELECT e -> email, ORDER BY cre -> created_at) now
completes columns of the tables referenced in the current statement's
FROM/JOIN clauses, even when the schema defines many tables. Previously
this was delegated to @codemirror/lang-sql, which only offers top-level
columns with a single defaultTable configured.

- Add unqualifiedColumnCompletionSource with dot/table-position guards,
  per-statement scoping, join unions, CTE columns, and ambiguity safety
- Extract shared schema-resolution helpers into completion-utils.ts
- Wire into demo (sharing one QueryContextAnalyzer) and document in README
Copilot AI review requested due to automatic review settings July 23, 2026 17:54

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.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 90.92% 1653 / 1818
🔵 Statements 91.08% 1726 / 1895
🔵 Functions 94.69% 232 / 245
🔵 Branches 82.58% 1290 / 1562
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/index.ts 0% 0% 0% 0%
src/sql/alias-completion-source.ts 100% 88% 100% 100%
src/sql/column-completion-source.ts 96.61% 85.36% 100% 96.42% 72, 119
src/sql/completion-utils.ts 89.47% 77.77% 100% 87.87% 18, 23, 61, 70
src/sql/namespace-utils.ts 93.41% 78.39% 100% 93.33% 147, 156-168, 262, 317-333
Generated in workflow #653 for commit 991e53a by the Vitest Coverage Report Action

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/sql/column-completion-source.ts
Comment thread src/sql/column-completion-source.ts
Comment thread src/sql/completion-utils.ts Outdated
- Skip completion in comma-continued FROM table lists (FROM a, b, <cursor>)
  while still completing after commas in SELECT/GROUP BY lists
- Skip completion inside string literals and comments by reusing
  maskLiteralsAndComments from query-context
- Pass table path segments to findTableColumns/traverseNamespacePath so
  quoted identifiers containing dots (e.g. "my.table") resolve correctly
…-from-clause

# Conflicts:
#	README.md
#	src/index.ts
@mscolnick
mscolnick merged commit 991e53a into main Jul 23, 2026
5 checks passed
@mscolnick
mscolnick deleted the ms/infer-columns-from-from-clause branch July 23, 2026 18:32
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