[Feat]: SQL autocomplete — resolve CTEs and derived tables as column sources
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- sql, typescript
- Domain
- database, developer-experience
Research direction
Start by reading src/utils/sqlContext.ts for the existing parenthesis-matching and string/comment-skipping helpers, then inspect src/utils/autocomplete.ts to understand completion context and column lookup. Implement and test parsing in src/utils/derivedTables.ts with tests/utils/derivedTables.test.ts, then add provider integration coverage in tests/utils/autocomplete.test.ts. Done means CTEs and derived-table columns resolve in scope, explicit column lists take precedence, and inner-table columns do not leak into the outer scope.
Written by the indexing model from the issue text.
Description
Problem
Follow-up to #505. The completion provider only knows about physical tables, so anything defined inside the query itself is invisible to it:
WITH recent AS (SELECT id, occurred_at AS ts FROM events)
SELECT recent.| FROM recent
Typing recent. completes nothing — the dot trigger resolves the alias through get_columns, which asks the database, and the database has never heard of recent. Same story for derived tables:
SELECT x.| FROM (SELECT a, b FROM t) x
Both should complete id/ts and a/b respectively. This is the biggest functional gap left after #505, and it bites hardest exactly in the queries where autocomplete would help most.
There's also a related scope leak this fixes for free (see Integration below): today SELECT | FROM (SELECT ... FROM inner_t) x offers inner_t columns at the outer level, because the outer parse still sees the raw subquery text.
Design sketch
New module src/utils/derivedTables.ts — pure functions, no Monaco/Tauri imports, so it can be unit-tested exhaustively like sqlContext.ts:
parseDerivedTables(statementText: string): DerivedTable[]
interface DerivedTable {
name: string
columns: DerivedColumn[]
bodyStart: number // offsets of the inner SELECT, for scope checks
bodyEnd: number
}
interface DerivedColumn {
name: string
sourceExpression?: string
}
It needs to detect two shapes:
- CTE headers:
WITH [RECURSIVE] name [(col, ...)] AS ( ... ), including comma-separated lists of CTEs. - Derived tables in FROM/JOIN:
FROM ( SELECT ... ) [AS] alias [(col, ...)].
Column names come from the inner SELECT list, split on top-level commas (commas inside parens/strings don't count):
expr AS name→name; bare aliasexpr name→name- plain reference
t.colorcol→col - expression with no alias (function call, arithmetic) → no derivable name, skip it
*→ optionally fall back toget_columnson the underlying table; fine to punt on this in a first pass- an explicit column list on the alias (
x(a, b)) always wins over anything derived from the body
sqlContext.ts already has the paren-matching and string/comment-skipping machinery — extract shared helpers rather than duplicating that logic (getting doubled-quote escapes right twice is asking for drift).
Integration in autocomplete.ts
- Build a
Map<string, DerivedTable>per completion request from the current statement. - On dot trigger, check that map before falling through to physical tables via
get_columns. Detail label along the lines ofCTE recentso it's obvious where the column comes from. - For context columns (non-dot suggestions), treat in-scope derived tables as column sources next to the physical FROM tables.
- Nested case: a CTE body referencing an earlier CTE (
WITH a AS (...), b AS (SELECT ... FROM a)) — resolve iteratively in declaration order, each CTE seeing only the ones declared before it. - The outer-scope leak: once the derived table replaces the raw subquery text in the outer parse,
inner_tnaturally disappears from the outer scope. Worth an explicit test so it doesn't regress.
Tests
tests/utils/derivedTables.test.ts should cover: single CTE, multiple comma-separated CTEs, RECURSIVE, explicit column lists, both alias forms (AS name / bare), unnamed expressions, *, a CTE referencing a previous CTE, and quoted identifiers in all three styles. Plus provider-level integration tests in tests/utils/autocomplete.test.ts: dot trigger on a CTE alias, context columns inside vs. outside the CTE body, and the outer-scope leak case above.
Effort
Noticeably bigger than the subquery-scoping commit in #505 — roughly 2–3×. The top-level SELECT-list splitter is the fiddly part; everything else is bookkeeping.
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 335
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 280
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TabularisDB/tabularis
-
[Feat]: Text viewer: show character, line and UTF-8 byte countsPossibly taken @maxteneff claimed this 1 day ago. Openfeature request good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
TabularisDB/tabularis#1395 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
TabularisDB/tabularis#1434 ·
Maintainers usually reply within 1 day
-
[Bug]: SQLite REAL values of infinity show as NULL in the data gridPossibly taken @markankamaransheogarat-sys claimed this today. Open
TabularisDB/tabularis#1433 · 3 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
feature request help wanted
Difficulty 5/5 Over a week Newbie friendliness 38/100
TabularisDB/tabularis#1418 ·
Maintainers usually reply within 1 day
-
[Feat]: SQL editor: reusable snippets with tab-stop placeholdersPossibly taken @markankamaransheogarat-sys claimed this today. Openfeature request help wanted
Difficulty 5/5 Over a week Newbie friendliness 35/100
TabularisDB/tabularis#1417 · 2 comments · 1 assignee ·
Maintainers usually reply within 1 day
All issues in TabularisDB/tabularis
Similar issues
-
area:cards enhancement ready-for-agent
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
fil-donadoni/tolaria#8883 ·
Maintainers usually reply within 1 day
-
xsd:integer cast from a string rejects negative numbers, a leading + and surrounding whitespaceOpenbug 🐛
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
comunica/comunica#1960 · 1 comment ·
Maintainers usually reply within 1 day
-
Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
getsentry/sentry-javascript#26203 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bytedance/flowgram.ai#1235 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
devswha/herdr-web-ui#3325 ·