Skip to content

Quick fixes, more option checks, inlay hints and workspace symbols (0.5.0) - #32

Merged
valerypetrov merged 9 commits into
optionsfrom
release-050
Nov 6, 2026
Merged

valerypetrov merged 9 commits into
optionsfrom
release-050

Conversation

@valerypetrov

Copy link
Copy Markdown
Owner

Quick fixes, more option checks, inlay hints, hover for SYSTEM and access statements, and workspace symbols. Version 0.5.0. Builds on #31.

  • Quick fixes for errors that know the answer: the closest setting, codec, index or statistics type, format, compression method, enum value, keyword or test-hint error name; the names in the server check's "Maybe you meant"; quotes around a number for a one-character setting; ENGINE = MergeTree after SET default_table_engine = 'None'. Applying every offered fix and running the result in ClickHouse 26.11 (npm run oracle:fixes): 3,250 of 3,250 accepted.
  • More option checks: maps given to number and bool settings, float values, URIs, compatibility, unsigned -1, codecs on column types they don't take, Quantized and SZ3 parameters, text and vector_similarity index arguments, INTO OUTFILE ... LEVEL. npm run oracle:options misses, before → after: query settings 2,091 → 0, MergeTree settings 2,514 → 0, codecs 727 → 0, index types 53 → 11, compression levels 68 → 6. False errors stay 0, and false positives on the 271,063 statements of ClickHouse's tests stay 0.
  • Inlay hints, off by default (clickhouseSql.inlayHints.enabled): parameter names in function, table-function and engine calls, and the type of param_name. After an edit, the hints of one screen of the 1 MB stress file take 10 ms.
  • Hover over SYSTEM commands and the clauses of CREATE/ALTER USER, ROLE, QUOTA, ROW POLICY and SETTINGS PROFILE, generated from ClickHouse's docs.
  • Workspace symbols: Go to Symbol in Workspace lists the tables, views, dictionaries, functions and databases that CREATE statements make. Go to Definition and Find All References follow a table name across files, with the database USE sets. On ClickHouse's 12,400 test files, the first lookup takes 3.1 s and later ones 6 ms.
  • The ClickHouse release pipeline now regenerates the option rules and the new statement docs.

npm test: 1,621 tests, 0 failures. VS Code e2e: 81 passing on 1.145.2 (three runs) and on 1.90.0.

🤖 Generated with Claude Code

valerypetrov and others added 9 commits November 6, 2026 11:29
Inlay hints (clickhouseSql.inlayHints.enabled, off by default) show the
parameter name before each argument of a function, table function or
engine call with two arguments or more, from the signatures that
signature help already reads. parameterHints() in the library reuses
functionCall() and engineCall() at the start of each argument, and only
hints names that the parser gives the function or engine role, so
column lists, IN lists and types like Decimal(10, 2) get none. An
argument that already is a name equal to the parameter, an argument the
syntax leaves ambiguous and the arguments of a repeated parameter (as
in tuple()) get no hint. A param_name setting gets the type of its
{name:Type} when the file gives it one type. The provider returns
nothing while editor.inlayHints.enabled is off and refreshes when
either setting changes.

The provider reads only the statements on the screen through the
document's ParseCache, like the range semantic tokens; the stress test
times a 60-line screen of the 1 MB file after an edit (10 ms here).

Hover now documents SYSTEM commands and the clauses of CREATE and
ALTER USER, ROLE, QUOTA, ROW POLICY and SETTINGS PROFILE, which
completion already offered. scripts/generate-statements.ts reads
ClickHouse's docs/reference/statements: the commands from the headings
of system.mdx, with CLEAR|DROP and [REPLICATED] spelled out and the
forms that only a section's syntax names, and the clauses from the
sections and paragraphs named after them. keywordDocumentation() picks
the longest command after SYSTEM, or the clause whose keywords are at
the cursor, and the statement's syntax for other keywords. In access
statements only words that the parser reads as keywords count, so a
user called host gets no hover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diagnostics now carry `fixes`, each a title and the edits that apply it, so
the library can be tested without VS Code and the extension only turns them
into code actions of kind QuickFix.

The candidates follow ClickHouse's NamePrompter: names within a few typos,
closest first, and the one closer than all others is preferred. Unknown
settings, codecs, index and statistics types, formats, compression methods,
enum values and test hint error names get them; a codec or index type must
take the parameters written and a setting the value written. check()'s
"Maybe you meant" keyword is offered only when the statement then passes
check(), and the server check's "Maybe you meant" names are read by
messageFixes().

After SET default_table_engine = 'None', ClickHouse refuses a CREATE TABLE
without ENGINE (ENGINE_REQUIRED, checked with clickhouse local), so
checkOptions() now marks it, with ENGINE = MergeTree as the fix, and
ORDER BY tuple() where the table has no ORDER BY or PRIMARY KEY, since
create_table_empty_primary_key_by_default may be off on a server.

oracle:fixes applies every fix to typos generated from the catalogs and to
the invalid statements of the sample, and runs the results in clickhouse
local. Two kinds were narrowed until ClickHouse took every fix: settings keep
only their closest hints, as the checks of values miss some refusals, and a
number is quoted only for a setting of one character, since many settings of
strings check their values further (format, database, compatibility, ...).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Go to Symbol in Workspace now lists the tables, views, materialized views,
dictionaries, functions and databases that the CREATE statements of the
workspace's ClickHouse SQL files make, and go to definition and Find All
References follow a table name in FROM, JOIN, INSERT INTO, ALTER TABLE, DROP,
OPTIMIZE, RENAME, CREATE ... AS t, MV TO t and the other places that name a
table to its CREATE statement in any file.

The library gets three functions. objects() reads the CREATE and USE
statements from the tokens of split() only: a full parse of ClickHouse's
12,400 test files takes about 28 s, tokens alone under 1 s, so the index can
be built lazily on the first request. objectReferences() takes the names from
the parse instead, through a new "object" name mark where the parser reads a
[db.]table name, so that extract(DAY FROM d) or a column t.x is never taken
for a table; names analysis skips the new mark. objectDefinitions() resolves
a reference as ClickHouse would run each file in its own session, checked
with clickhouse local: an unqualified name means the database of the last
USE before it; a temporary table of the same file comes first and is never
seen from other files or through db.t; in the same file the last CREATE
before the name wins; where the database is not known, every table of that
name that may be meant is offered rather than guessing. A CTE of the
statement takes the place of a table of its name.

The extension keeps the index per file, with open documents read from their
current text, follows a file watcher on the same globs that open files as
ClickHouse SQL (.chsql, .clickhouse.sql and files.associations entries), and
skips files longer than clickhouseSql.maxFileSize without reading those that
are certainly too long. A change of files.associations or maxFileSize drops
the index. Find All References parses the files that contain the name and
keeps the references whose definitions include the one at the cursor.
In-file definitions of aliases and CTEs keep precedence. workspaceContains
activation events let Ctrl+T work before a ClickHouse file is opened.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The options oracle measured values that ClickHouse refuses and checkOptions()
let through: a map given to a numeric or boolean setting, float settings given
'', a size suffix or 'inf', integers a float setting cannot hold exactly,
seconds too large for microseconds, '-1' for an unsigned setting, URIs,
compatibility versions and BoolForce; codecs on column types they do not take;
the counts and parameters of Quantized and SZ3; the arguments of the text and
vector_similarity indexes; and the LEVEL of INTO OUTFILE.

A map in a settings value was mistaken for a query parameter and skipped; it
is now read, and written in messages as ClickHouse writes the Field.

The new rules come from the binary. generate-options.ts asks each codec about
every data type family, bare and with parameters, and keeps the refusals that
name the type; checkOptions() looks through Nullable, LowCardinality, Array,
Map and Tuple to the types a column holds, and skips columns without a written
type or with types it was not asked about. It probes the levels of each
compression method, the named arguments of the text index (names from its
source, tokenizers from system.tokenizers), and Quantized, SZ3 and
vector_similarity from a base call. A probe value a base call has that the
probe list lacks is added, an unknown string is refused only when the refusal
is about its kind or the probes cover the values, counts the message states
or refuses between min and max are kept, and a value a setting would allow is
counted as taken, so none of this can refuse a valid statement.

The oracle now checks codecs on more column types, counts type refusals,
probes the text and vector_similarity arguments and compression levels, and
reads a test hint inside a statement as expected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	ARCHITECTURE.md
#	packages/core/src/options/check.ts
#	packages/vscode/CHANGELOG.md
#	packages/vscode/README.md
# Conflicts:
#	packages/vscode/CHANGELOG.md
#	packages/vscode/package.json
#	packages/vscode/test/e2e/index.ts
# Conflicts:
#	packages/core/src/index.ts
#	packages/vscode/CHANGELOG.md
#	packages/vscode/package.json
#	packages/vscode/src/extension.ts
#	packages/vscode/src/settings.ts
#	packages/vscode/test/e2e/index.ts
The release pipeline regenerated the keywords, the catalog and the grammar, but not the
options of checkOptions() or the docs of SYSTEM commands and access-statement clauses, so
those would stay at the build they were made from. It now runs generate-options.ts and
generate-statements.ts too, and checks out the sources and docs they read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@valerypetrov
valerypetrov merged commit d832d86 into options Nov 6, 2026
10 checks passed
@valerypetrov valerypetrov mentioned this pull request Nov 6, 2026
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