Skip to content

fix(editor): teach auto-uppercase every keyword autocomplete offers - #2912

Merged
datlechin merged 2 commits into
mainfrom
fix/keyword-uppercase-vocabulary-drift
Sep 16, 2026
Merged

datlechin merged 2 commits into
mainfrom
fix/keyword-uppercase-vocabulary-drift

Conversation

@datlechin

Copy link
Copy Markdown
Member

Two lists decide what counts as a SQL keyword and nothing made them agree. Found while investigating #2833.

The defect

SQLKeywords.keywordSet is built from SQLKeywords.keywords alone, and it is the only vocabulary Auto-uppercase consults. The completion provider offers keywords from 31 clause-specific arrays written inline in getCandidates, and 21 single words in those arrays were never added to the catalogue.

Reproduction. Settings > Editor, turn on Auto-uppercase keywords. Type:

alter table users add column note text;

Result: ALTER TABLE users add COLUMN note TEXT;

add is the one word left alone, because ALTER, TABLE, COLUMN and TEXT are in the catalogue and ADD is not, even though autocomplete had offered ADD a keystroke earlier. Same shape for merge into ... and call proc().

The fix

The 21 missing words go into SQLKeywords.keywords, in the groups they belong to: ADD, CHANGE, AFTER, COMMENT, COLLATE, CHARSET, ENGINE, TABLESPACE, MERGE, UPSERT, REPLACE, CALL, USE, SIGNED, UNSIGNED, RANGE, GROUPS, and the index access methods BTREE, HASH, GIN, GIST.

The index methods are included deliberately. They are unreserved keywords in the CREATE INDEX ... USING position, uppercasing them produces valid SQL, and excluding four words on the grounds that they might also be column names is exactly the unprincipled special-casing that produced the gap. DATE, TEXT, KEY, SET and TIME already have that property and are already in the catalogue.

Why a test rather than a refactor

The structural fix would be to hoist all 31 clause arrays into SQLKeywords so one union feeds both consumers. I did not, because those arrays are what makes each arm of getCandidates readable, and that function is already at the SwiftLint body limit; replacing 31 inline vocabularies with 31 constant names moves the cost rather than removing it.

KeywordVocabularyParityTests instead reads SQLCompletionProvider.swift and fails when it offers a single-word keyword the catalogue does not hold. You cannot now add a keyword to a clause arm without teaching the uppercaser about it. This is the shape the repo already uses for the same class of problem, in HealthMonitorOptOutParityTests and SyncMapperFieldAccessTests.

The guard catches the original defect. Run against the unfixed catalogue it fails offeredKeywordsAreUppercasable, reportedStatementUppercasesConsistently, and every case of reportedKeywordsAreKnown.

Verification

generate PASS, test PASS (231 of 231 across KeywordVocabularyParityTests, SQLKeywordsTests, KeywordUppercaseHelperTests, SQLCompletionProviderTests, CompletionEngineTests), lint PASS.

Docs already describe the setting generically ("Uppercases SQL keywords on word boundaries"), which stays accurate.

No UI change, so no screenshots.

Note

This and #2902 both add a line under ### Fixed in the CHANGELOG, so whichever merges second needs that one-line rebase. They touch no source file in common.

@datlechin
datlechin merged commit 0d66dab into main Sep 16, 2026
9 checks passed
@datlechin
datlechin deleted the fix/keyword-uppercase-vocabulary-drift branch September 16, 2026 04:04
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.

1 participant