Skip to content

Commit 510997c

Browse files
committed
Checkpoint tests
1 parent d457a98 commit 510997c

File tree

3 files changed

+1602
-36
lines changed

3 files changed

+1602
-36
lines changed

src/languages/clickhouse/clickhouse.formatter.ts

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { EOF_TOKEN, Token, TokenType } from '../../lexer/token.js';
44
import { functions } from './clickhouse.functions.js';
55
import { dataTypes, keywords } from './clickhouse.keywords.js';
66

7-
const reservedSelect = expandPhrases(['SELECT [DISTINCT]']);
7+
const reservedSelect = expandPhrases([
8+
'SELECT [DISTINCT]',
9+
// https://clickhouse.com/docs/sql-reference/statements/alter/view
10+
'MODIFY QUERY SELECT [DISTINCT]',
11+
]);
812

913
const reservedClauses = expandPhrases([
1014
'SET',
@@ -28,17 +32,35 @@ const reservedClauses = expandPhrases([
2832
// https://clickhouse.com/docs/sql-reference/statements/insert-into
2933
'INSERT INTO',
3034
'VALUES',
35+
'DEPENDS ON',
36+
// https://clickhouse.com/docs/sql-reference/statements/move
37+
'MOVE {USER | ROLE | QUOTA | SETTINGS PROFILE | ROW POLICY}',
38+
// https://clickhouse.com/docs/sql-reference/statements/grant
39+
'GRANT',
40+
// https://clickhouse.com/docs/sql-reference/statements/revoke
41+
'REVOKE',
42+
// https://clickhouse.com/docs/sql-reference/statements/check-grant
43+
'CHECK GRANT',
44+
// https://clickhouse.com/docs/sql-reference/statements/set-role
45+
'SET [DEFAULT] ROLE [NONE | ALL | ALL EXCEPT]',
46+
// https://clickhouse.com/docs/sql-reference/statements/optimize
47+
'DEDUPLICATE BY',
48+
// https://clickhouse.com/docs/sql-reference/statements/alter/statistics
49+
'MODIFY STATISTICS',
50+
'TYPE',
3151
]);
3252

3353
const standardOnelineClauses = expandPhrases([
3454
// https://clickhouse.com/docs/sql-reference/statements/create
3555
'CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS]',
3656
]);
3757
const tabularOnelineClauses = expandPhrases([
58+
'ALL EXCEPT',
59+
'ON CLUSTER',
3860
// https://clickhouse.com/docs/sql-reference/statements/update
3961
'UPDATE',
4062
// https://clickhouse.com/docs/sql-reference/statements/system
41-
'SYSTEM RELOAD {DICTIONARIES | DICTIONARY | FUNCTIONS | FUNCTION | ASYNCHRONOUS METRICS} [ON CLUSTER]',
63+
'SYSTEM RELOAD {DICTIONARIES | DICTIONARY | FUNCTIONS | FUNCTION | ASYNCHRONOUS METRICS}',
4264
'SYSTEM DROP {DNS CACHE | MARK CACHE | ICEBERG METADATA CACHE | TEXT INDEX DICTIONARY CACHE | TEXT INDEX HEADER CACHE | TEXT INDEX POSTINGS CACHE | REPLICA | DATABASE REPLICA | UNCOMPRESSED CACHE | COMPILED EXPRESSION CACHE | QUERY CONDITION CACHE | QUERY CACHE | FORMAT SCHEMA CACHE | FILESYSTEM CACHE}',
4365
'SYSTEM FLUSH LOGS',
4466
'SYSTEM RELOAD {CONFIG | USERS}',
@@ -56,6 +78,7 @@ const tabularOnelineClauses = expandPhrases([
5678
'SYSTEM {STOP | START} [REPLICATED] VIEW',
5779
'SYSTEM {STOP | START} VIEWS',
5880
'SYSTEM {REFRESH | CANCEL | WAIT} VIEW',
81+
'WITH NAME',
5982
// https://clickhouse.com/docs/sql-reference/statements/show
6083
'SHOW [CREATE] {TABLE | TEMPORARY TABLE | DICTIONARY | VIEW | DATABASE}',
6184
'SHOW DATABASES [[NOT] {LIKE | ILIKE}]',
@@ -65,32 +88,28 @@ const tabularOnelineClauses = expandPhrases([
6588
'ATTACH {TABLE | DICTIONARY | DATABASE} [IF NOT EXISTS]',
6689
// https://clickhouse.com/docs/sql-reference/statements/detach
6790
'DETACH {TABLE | DICTIONARY | DATABASE} [IF EXISTS]',
91+
'PERMANENTLY',
92+
'SYNC',
6893
// https://clickhouse.com/docs/sql-reference/statements/drop
6994
'DROP {DICTIONARY | DATABASE | USER | ROLE | QUOTA | PROFILE | SETTINGS PROFILE | VIEW | FUNCTION | NAMED COLLECTION | ROW POLICY | POLICY} [IF EXISTS]',
7095
'DROP [TEMPORARY] TABLE [IF EXISTS] [IF EMPTY]',
7196
// https://clickhouse.com/docs/sql-reference/statements/exists
7297
'EXISTS [TEMPORARY] {TABLE | DICTIONARY | DATABASE}',
7398
// https://clickhouse.com/docs/sql-reference/statements/kill
74-
'KILL QUERY [ON CLUSTER]',
99+
'KILL QUERY',
75100
// https://clickhouse.com/docs/sql-reference/statements/optimize
76101
'OPTIMIZE TABLE',
77102
// https://clickhouse.com/docs/sql-reference/statements/rename
78103
'RENAME [TABLE | DICTIONARY | DATABASE]',
79104
// https://clickhouse.com/docs/sql-reference/statements/exchange
80105
'EXCHANGE {TABLES | DICTIONARIES}',
81-
// https://clickhouse.com/docs/sql-reference/statements/set-role
82-
'SET ROLE [DEFAULT | NONE | ALL | ALL EXCEPT]',
83-
'SET DEFAULT ROLE [NONE]',
84106
// https://clickhouse.com/docs/sql-reference/statements/truncate
85107
'TRUNCATE TABLE [IF EXISTS]',
86108
// https://clickhouse.com/docs/sql-reference/statements/execute_as
87109
'EXECUTE AS',
88110
// https://clickhouse.com/docs/sql-reference/statements/use
89111
'USE',
90-
// https://clickhouse.com/docs/sql-reference/statements/move
91-
'MOVE {USER | ROLE | QUOTA | SETTINGS PROFILE | ROW POLICY}',
92-
// https://clickhouse.com/docs/sql-reference/statements/check-grant
93-
'CHECK GRANT',
112+
'TO',
94113
// https://clickhouse.com/docs/sql-reference/statements/undrop
95114
'UNDROP TABLE',
96115
// https://clickhouse.com/docs/sql-reference/statements/create
@@ -109,7 +128,6 @@ const tabularOnelineClauses = expandPhrases([
109128
'ALTER NAMED COLLECTION [IF EXISTS]',
110129
// https://clickhouse.com/docs/sql-reference/statements/alter/user
111130
'RENAME TO',
112-
'DEFAULT ROLE [ALL [EXCEPT]]',
113131
'GRANTEES',
114132
'NOT IDENTIFIED',
115133
'RESET AUTHENTICATION METHODS TO NEW',
@@ -120,7 +138,8 @@ const tabularOnelineClauses = expandPhrases([
120138
'{ADD | MODIFY} SETTINGS',
121139
'ADD PROFILES',
122140
// https://clickhouse.com/docs/sql-reference/statements/alter/apply-deleted-mask
123-
'APPLY DELETED MASK [IN PARTITION]',
141+
'APPLY DELETED MASK',
142+
'IN PARTITION',
124143
// https://clickhouse.com/docs/sql-reference/statements/alter/column
125144
'{ADD | DROP | RENAME | CLEAR | COMMENT | MODIFY | ALTER | MATERIALIZE} COLUMN',
126145
// https://clickhouse.com/docs/sql-reference/statements/alter/partition
@@ -142,6 +161,11 @@ const tabularOnelineClauses = expandPhrases([
142161
'{MODIFY | REMOVE} SAMPLE BY',
143162
// https://clickhouse.com/docs/sql-reference/statements/alter/skipping-index
144163
'{ADD | MATERIALIZE | CLEAR} INDEX [IF NOT EXISTS]',
164+
'DROP INDEX [IF EXISTS]',
165+
'GRANULARITY',
166+
'AFTER',
167+
'FIRST',
168+
145169
// https://clickhouse.com/docs/sql-reference/statements/alter/constraint
146170
'ADD CONSTRAINT [IF NOT EXISTS]',
147171
'DROP CONSTRAINT [IF EXISTS]',
@@ -150,7 +174,6 @@ const tabularOnelineClauses = expandPhrases([
150174
'REMOVE TTL',
151175
// https://clickhouse.com/docs/sql-reference/statements/alter/statistics
152176
'ADD STATISTICS [IF NOT EXISTS]',
153-
'MODIFY STATISTICS',
154177
'{DROP | CLEAR} STATISTICS [IF EXISTS]',
155178
'MATERIALIZE STATISTICS [ALL | IF EXISTS]',
156179
// https://clickhouse.com/docs/sql-reference/statements/alter/quota
@@ -163,23 +186,25 @@ const tabularOnelineClauses = expandPhrases([
163186
// https://clickhouse.com/docs/sql-reference/statements/alter/projection
164187
'ADD PROJECTION [IF NOT EXISTS]',
165188
'{DROP | MATERIALIZE | CLEAR} PROJECTION [IF EXISTS]',
166-
// https://clickhouse.com/docs/sql-reference/statements/alter/view
167-
'MODIFY QUERY',
168189
// https://clickhouse.com/docs/sql-reference/statements/create/view#refreshable-materialized-view
169190
'REFRESH {EVERY | AFTER}',
170191
'RANDOMIZE FOR',
171-
'DEPENDS ON',
192+
'APPEND',
172193
'APPEND TO',
173194
// https://clickhouse.com/docs/sql-reference/statements/delete
174195
'DELETE FROM',
175196
// https://clickhouse.com/docs/sql-reference/statements/explain
176197
'EXPLAIN [AST | SYNTAX | QUERY TREE | PLAN | PIPELINE | ESTIMATE | TABLE OVERRIDE]',
177198
// https://clickhouse.com/docs/sql-reference/statements/grant
178-
'GRANT [ON CLUSTER]',
199+
'GRANT ON CLUSTER',
200+
'GRANT CURRENT GRANTS',
201+
'WITH GRANT OPTION',
179202
// https://clickhouse.com/docs/sql-reference/statements/revoke
180-
'REVOKE [ON CLUSTER]',
203+
'REVOKE ON CLUSTER',
204+
'ADMIN OPTION FOR',
181205
// https://clickhouse.com/docs/sql-reference/statements/check-table
182206
'CHECK TABLE',
207+
'PARTITION ID',
183208
// https://clickhouse.com/docs/sql-reference/statements/describe-table
184209
'{DESC | DESCRIBE} TABLE',
185210
]);
@@ -196,7 +221,10 @@ const reservedJoins = expandPhrases([
196221
'[GLOBAL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI|ANY|ALL|ASOF] JOIN',
197222
]);
198223

199-
const reservedKeywordPhrases = expandPhrases(['{ROWS | RANGE} BETWEEN']);
224+
const reservedKeywordPhrases = expandPhrases([
225+
'{ROWS | RANGE} BETWEEN',
226+
'ALTER MATERIALIZE STATISTICS',
227+
]);
200228

201229
// https://clickhouse.com/docs/sql-reference/syntax
202230
export const clickhouse: DialectOptions = {
@@ -260,15 +288,15 @@ export const clickhouse: DialectOptions = {
260288
*/
261289
function postProcess(tokens: Token[]): Token[] {
262290
return tokens.map((token, i) => {
291+
const nextToken = tokens[i + 1] || EOF_TOKEN;
292+
const prevToken = tokens[i - 1] || EOF_TOKEN;
293+
263294
// Only process IN and ANY that are currently RESERVED_FUNCTION_NAME
264295
// Check text (uppercase canonical form) for matching, but preserve raw (original casing)
265296
if (
266297
token.type === TokenType.RESERVED_FUNCTION_NAME &&
267298
(token.text === 'IN' || token.text === 'ANY')
268299
) {
269-
const nextToken = tokens[i + 1] || EOF_TOKEN;
270-
const prevToken = tokens[i - 1] || EOF_TOKEN;
271-
272300
// Must be followed by ( to be a function
273301
if (nextToken.text !== '(') {
274302
// Not followed by ( means it's an operator/keyword, convert to uppercase
@@ -293,6 +321,37 @@ function postProcess(tokens: Token[]): Token[] {
293321
// Otherwise, keep as RESERVED_FUNCTION_NAME to preserve original casing via functionCase option
294322
}
295323

324+
// If we have queries like
325+
// > GRANT SELECT, INSERT ON db.table TO john
326+
// > GRANT SELECT(a, b), SELECT(c) ON db.table TO john
327+
// we want to format them as
328+
// > GRANT
329+
// > SELECT,
330+
// > INSERT ON db.table
331+
// > TO john
332+
// > GRANT
333+
// > SELECT(a, b),
334+
// > SELECT(c) ON db.table
335+
// > TO john
336+
// To do this we need to convert the SELECT keyword to a RESERVED_KEYWORD.
337+
if (
338+
token.type === TokenType.RESERVED_SELECT &&
339+
(nextToken.type === TokenType.COMMA ||
340+
prevToken.type === TokenType.RESERVED_CLAUSE ||
341+
prevToken.type === TokenType.COMMA)
342+
) {
343+
return { ...token, type: TokenType.RESERVED_KEYWORD };
344+
}
345+
346+
// We should format `set(100)` as-is rather than `SET (100)`
347+
if (
348+
token.type === TokenType.RESERVED_CLAUSE &&
349+
token.text === 'SET' &&
350+
nextToken.type === TokenType.OPEN_PAREN
351+
) {
352+
return { ...token, type: TokenType.RESERVED_FUNCTION_NAME, text: token.raw };
353+
}
354+
296355
return token;
297356
});
298357
}

src/languages/clickhouse/clickhouse.functions.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ export const functions: string[] = [
292292
'atan',
293293
'atan2',
294294
'atanh',
295+
'authenticatedUser',
295296
'avg',
296297
'avgWeighted',
297298
'bar',
@@ -1026,6 +1027,7 @@ export const functions: string[] = [
10261027
'nullIf',
10271028
'nullIn',
10281029
'nullInIgnoreSet',
1030+
'numbers',
10291031
'numericIndexedVectorAllValueSum',
10301032
'numericIndexedVectorBuild',
10311033
'numericIndexedVectorCardinality',
@@ -1282,6 +1284,7 @@ export const functions: string[] = [
12821284
'serverTimeZone',
12831285
'serverTimezone',
12841286
'serverUUID',
1287+
'set',
12851288
'shardCount',
12861289
'shardNum',
12871290
'showCertificate',
@@ -1721,4 +1724,28 @@ export const functions: string[] = [
17211724
'yearweek',
17221725
'yesterday',
17231726
'zookeeperSessionUptime',
1727+
1728+
// Table Engines
1729+
// https://clickhouse.com/docs/engines/table-engines
1730+
'MergeTree',
1731+
'ReplacingMergeTree',
1732+
'SummingMergeTree',
1733+
'AggregatingMergeTree',
1734+
'CollapsingMergeTree',
1735+
'VersionedCollapsingMergeTree',
1736+
'GraphiteMergeTree',
1737+
'CoalescingMergeTree',
1738+
1739+
// Database Engines
1740+
// https://clickhouse.com/docs/engines/database-engines
1741+
'Atomic',
1742+
'Shared',
1743+
'Lazy',
1744+
'Replicated',
1745+
'PostgreSQL',
1746+
'MySQL',
1747+
'SQLite',
1748+
'Backup',
1749+
'MaterializedPostgreSQL',
1750+
'DataLakeCatalog',
17241751
];

0 commit comments

Comments
 (0)