Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
62367cf
test: add server-query parity harness
emrberk Nov 10, 2026
f46bcad
feat: parse hex, float-suffix, E'...' and typed literals
emrberk Nov 10, 2026
a964c1c
feat: parse GROUP BY / SAMPLE BY ROLLUP, CUBE and GROUPING SETS
emrberk Nov 10, 2026
ac9b186
feat: parse DEDUP SKIP, the DEDUPLICATE synonym and ALTER DEDUP witho…
emrberk Nov 10, 2026
e59df46
fix: require ON in EXPIRE ROWS KEEP HIGHEST|LOWEST and end WHEN at IN…
emrberk Nov 10, 2026
ac28eef
feat: parse implicit select bodies in mat views, CTAS, views and COPY
emrberk Nov 10, 2026
55c8518
fix: unescape '' in single-quoted statement values so they round-trip
emrberk Nov 10, 2026
52c8d03
fix: end duration literals at a word boundary and add the ns unit
emrberk Nov 10, 2026
65d4abd
feat: parse bind variables $n and :name
emrberk Nov 10, 2026
8624c3c
feat: lex backtick-quoted identifiers and $ inside identifiers
emrberk Nov 10, 2026
82f521b
feat: nest block comments, run unterminated ones to the end, skip emp…
emrberk Nov 10, 2026
b602c4a
feat: type 99m / 1d as decimal / double numbers in expressions, lex 1…
emrberk Nov 10, 2026
3765d8c
feat: parse AT TIME ZONE, timestamp WITH TIME ZONE casts and DOUBLE P…
emrberk Nov 10, 2026
9b08b99
feat: parse IS [NOT] TRUE/FALSE, <> ALL (...) and NOT WITHIN
emrberk Nov 10, 2026
0065ffd
feat: parse GROUPS window frames and EXCLUDE GROUP / EXCLUDE TIES
emrberk Nov 10, 2026
1fe1a17
feat: parse (expr).member, stacked unary / NOT operands and chained c…
emrberk Nov 10, 2026
764aea0
feat: DECLARE AUDITED/OVERRIDABLE markers, trailing commas, implicit …
emrberk Nov 10, 2026
c89a663
feat: SAMPLE BY <expr> [unit], FILL(<expr>, ...), ALIGN TO ... TIME Z…
emrberk Nov 10, 2026
e1ef5c0
feat: accept server clause orders (LATEST before WHERE/SAMPLE BY, PIV…
emrberk Nov 10, 2026
731cf41
feat: PIVOT alias after `)`, FOR <expr> IN, IN values aliased without AS
emrberk Nov 10, 2026
217346a
feat: join clause words after the joined table, HORIZON JOIN optional…
emrberk Nov 10, 2026
8336103
feat: schema-qualified table functions in FROM/JOIN, UNION DISTINCT
emrberk Nov 10, 2026
84c258f
feat: CREATE/ALTER TABLE [NOT] NULL column modifiers, CTAS CAST symbo…
emrberk Nov 10, 2026
a9922f7
feat: CREATE MATERIALIZED VIEW TTL without PARTITION BY, bare/DEFERRE…
emrberk Nov 10, 2026
cd66977
feat: ALTER TABLE ADD without COLUMN, per-column IF NOT EXISTS, RENAM…
emrberk Nov 10, 2026
21c786e
feat: CONVERT PARTITION TO PARQUET|NATIVE LIST .. [WITH (..)]
emrberk Nov 10, 2026
322b503
fix: ALTER MATERIALIZED VIEW SUSPEND WAL WITH <code|'tag'>, '<message>'
emrberk Nov 10, 2026
9f19dad
feat: PG session statements BEGIN/COMMIT/ROLLBACK, DEALLOCATE, SET, D…
emrberk Nov 10, 2026
9ad7294
feat: DROP ALL without TABLES, UPDATE t AS alias, COPY TO quoted code…
emrberk Nov 10, 2026
c0cb207
feat: POSTING_DELTA/POSTING_EF, PARQUET byte_stream_split/default cod…
emrberk Nov 10, 2026
0afa016
feat: functions list — missing table-valued/scalar names, files() tab…
emrberk Nov 10, 2026
590b9b6
feat: join/clause/statement words usable as identifiers (server non-r…
emrberk Nov 10, 2026
e0509dc
feat: Enterprise resource groups (CREATE/ALTER/DROP RESOURCE GROUP, S…
emrberk Nov 10, 2026
0df1fe1
feat: Enterprise CREATE [OR REPLACE] VIEW ... WITH AUDIT [OWNED BY x]
emrberk Nov 10, 2026
23830d3
feat: Enterprise GRANT/REVOKE — all permission names, WITH VERIFICATI…
emrberk Nov 10, 2026
c7bc2b9
feat: Enterprise ADD COLUMN OWNED BY, quoted memory limits, unquoted …
emrberk Nov 10, 2026
40de251
fix: keep `arr[offset :n]` an array slice
emrberk Nov 11, 2026
1a3f642
fix: stop the UNNEST implicit alias at join / clause words
emrberk Nov 11, 2026
5b6b5c6
fix: only suggest LIMIT in GRANT/REVOKE where a permission continues …
emrberk Nov 11, 2026
28733ad
fix: never capitalize unquoted password values
emrberk Nov 11, 2026
10e39ec
docs: record known limitations and accepted tradeoffs
emrberk Nov 11, 2026
f367be1
fix: CASE ... END and keyword-named columns as array slice bounds
emrberk Nov 11, 2026
eb8b2e5
fix: read an unquoted password as one value; no keyword suggestions t…
emrberk Nov 11, 2026
49c48e9
fix: drop column-type and resource-group suggestions the server rejects
emrberk Nov 11, 2026
b104836
feat: suggest columns in DEDUP KEYS and EXPIRE ROWS KEEP ... ON / PAR…
emrberk Nov 11, 2026
bb9c9fb
docs: correct and extend known limitations after the PR #42 audit
emrberk Nov 11, 2026
f629f83
fix: decide slice vs bind by the innermost delimiter; WHEN/THEN/ELSE …
emrberk Nov 11, 2026
ca7e934
fix: stop password gluing at quoted tokens; accept any word as a pass…
emrberk Nov 11, 2026
45ec94d
fix: scope DEDUP KEYS / EXPIRE ROWS column suggestions to the object …
emrberk Nov 11, 2026
f6d62d4
docs: describe remaining gaps as deferred; UI issues are visible today
emrberk Nov 11, 2026
3ff4943
fix: keep IS / ILIKE / DECLARE column names as written under capitalize
emrberk Nov 11, 2026
4ea5bfb
fix: accept parenthesized and DECLARE grouping keys in ROLLUP / CUBE …
emrberk Nov 11, 2026
4eb1baa
fix: accept @ and $ in unquoted passwords
emrberk Nov 11, 2026
5205d84
fix: resolve key-column suggestions through CTAS and nested query output
emrberk Nov 11, 2026
5e3ee72
fix: capitalize each statement that parses, even if another one does not
emrberk Nov 11, 2026
e00cdcb
docs: record what the PR #42 reviews fixed and what is deferred
emrberk Nov 11, 2026
bd09000
fix: accept a bare @ in unquoted passwords (@123, abc@123, abc@)
emrberk Nov 11, 2026
2a26e55
fix: resolve key-column output through joins, qualified stars and CTEs
emrberk Nov 11, 2026
4bd195f
docs: narrow the password and key-column rows of the PR #42 review st…
emrberk Nov 11, 2026
4278924
docs: replace KNOWN_LIMITATIONS.md with gaps.md
emrberk Nov 11, 2026
baf7fc8
docs: drop gaps.md from the PR
emrberk Nov 11, 2026
10d9232
fix: GRANT / REVOKE suggestions follow the server permission names
emrberk Nov 11, 2026
29866b2
fix: keep selectBody a direct child of selectStatement after DECLARE …
emrberk Nov 11, 2026
ffbcb78
fix: scope retention predicates to materialized view columns
emrberk Nov 11, 2026
f498186
fix: preserve unquoted password values when formatting
emrberk Nov 11, 2026
148e512
fix: omit unsupported materialized view storage completions
emrberk Nov 11, 2026
ce1cdc8
fix: lex @1 and @foo$bar as one variable name
emrberk Nov 12, 2026
e215414
feat: parse double precision '...' as a typed literal
emrberk Nov 12, 2026
0c429ea
fix: refine catalog completion and array classification
emrberk Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions src/autocomplete/budgeted-content-assist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,43 @@ import {
Rule,
Terminal,
} from "chevrotain"
import { parser } from "../parser/parser"
import {
ALIAS_STOP_STATEMENT_TOKENS,
IMPLICIT_ALIAS_STOP_TOKENS,
parser,
} from "../parser/parser"
import { As, Case, IdentifierKeyword, Semicolon, When } from "../parser/lexer"

// The parser's implicit-alias GATEs (a join / clause / statement word is not
// an alias without AS), which content assist would otherwise ignore: the
// alias path would consume e.g. `ASOF` in `FROM t ASOF JOIN u` and prune the
// join path.
function isStoppedIdentifier(
terminalType: TokenType,
ruleStack: string[],
tokenVector: IToken[],
idx: number,
): boolean {
if (terminalType !== IdentifierKeyword) return false
// `CASE WHEN`: never a simple-CASE operand named `when`
const tokenType = tokenVector[idx].tokenType
if (tokenType === When && idx > 0 && tokenVector[idx - 1].tokenType === Case)
return true
// `SHOW `, `COPY `, `GRANT ` ...: a statement keyword, not the table of an
// implicit SELECT (`show WHERE ...`) at statement start
if (
ALIAS_STOP_STATEMENT_TOKENS.has(tokenType) &&
(idx === 0 || tokenVector[idx - 1].tokenType === Semicolon) &&
(ruleStack.includes("implicitSelectStatement") ||
ruleStack.includes("pivotStatement"))
)
return true
const n = ruleStack.length
if (n < 2 || ruleStack[n - 1] !== "identifier") return false
const stops = IMPLICIT_ALIAS_STOP_TOKENS.get(ruleStack[n - 2])
if (!stops || !stops.has(tokenVector[idx].tokenType)) return false
return idx === 0 || tokenVector[idx - 1].tokenType !== As
}

export interface ContentAssistSuggestion {
nextTokenType: TokenType
Expand Down Expand Up @@ -147,7 +183,15 @@ function nextPossibleTokensAfterBudgeted(
if (currIdx < tokenVectorLength - 1) {
const nextIdx = currIdx + 1
const actualToken = tokenVector[nextIdx]
if (tokMatcher(actualToken, prod.terminalType)) {
if (
tokMatcher(actualToken, prod.terminalType) &&
!isStoppedIdentifier(
prod.terminalType,
currRuleStack,
tokenVector,
nextIdx,
)
) {
possiblePaths.push({
idx: nextIdx,
def: currDef.slice(1),
Expand Down
Loading
Loading