@chkit/clickhouse 0.1.2-beta.5 → 0.2.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canonicalize.d.ts +21 -0
- package/dist/canonicalize.d.ts.map +1 -0
- package/dist/canonicalize.js +70 -0
- package/dist/canonicalize.js.map +1 -0
- package/dist/create-dictionary-parser.d.ts +6 -0
- package/dist/create-dictionary-parser.d.ts.map +1 -1
- package/dist/create-dictionary-parser.js +84 -10
- package/dist/create-dictionary-parser.js.map +1 -1
- package/dist/create-table-parser.d.ts.map +1 -1
- package/dist/create-table-parser.js +63 -46
- package/dist/create-table-parser.js.map +1 -1
- package/dist/ddl-propagation.d.ts +1 -0
- package/dist/ddl-propagation.d.ts.map +1 -1
- package/dist/ddl-propagation.js +62 -15
- package/dist/ddl-propagation.js.map +1 -1
- package/dist/e2e-testkit.d.ts +24 -5
- package/dist/e2e-testkit.d.ts.map +1 -1
- package/dist/e2e-testkit.js +50 -12
- package/dist/e2e-testkit.js.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/ddl-propagation.js
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import pRetry from 'p-retry';
|
|
2
2
|
const RETRY_OPTIONS = { retries: 20, minTimeout: 500, factor: 1 };
|
|
3
|
+
// What each ALTER or rename appends to the `<kind>:<database>.<name>` key of the
|
|
4
|
+
// object it changes. Creates and drops use the bare key.
|
|
5
|
+
const KEY_SUFFIXES = new Map([
|
|
6
|
+
['alter_materialized_view_modify_refresh', ':refresh'],
|
|
7
|
+
['alter_table_add_column', ':column:'],
|
|
8
|
+
['alter_table_modify_column', ':column:'],
|
|
9
|
+
['alter_table_drop_column', ':column:'],
|
|
10
|
+
['alter_table_rename_column', ':column_rename:'],
|
|
11
|
+
['alter_table_add_index', ':index:'],
|
|
12
|
+
['alter_table_drop_index', ':index:'],
|
|
13
|
+
['alter_table_add_projection', ':projection:'],
|
|
14
|
+
['alter_table_drop_projection', ':projection:'],
|
|
15
|
+
['alter_table_modify_setting', ':setting:'],
|
|
16
|
+
['alter_table_reset_setting', ':setting:'],
|
|
17
|
+
['alter_table_modify_ttl', ':ttl'],
|
|
18
|
+
['alter_table_rename_table', ':rename_table'],
|
|
19
|
+
['rename_dictionary', ':rename_dictionary'],
|
|
20
|
+
]);
|
|
3
21
|
export async function waitForTable(executor, database, tableName) {
|
|
4
22
|
await pRetry(async () => {
|
|
5
|
-
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database =
|
|
23
|
+
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database = ${stringLiteral(database)} AND name = ${stringLiteral(tableName)}`);
|
|
6
24
|
if (rows.length === 0) {
|
|
7
25
|
throw new Error(`waitForTable: ${database}.${tableName} not yet visible`);
|
|
8
26
|
}
|
|
@@ -10,15 +28,23 @@ export async function waitForTable(executor, database, tableName) {
|
|
|
10
28
|
}
|
|
11
29
|
export async function waitForView(executor, database, viewName) {
|
|
12
30
|
await pRetry(async () => {
|
|
13
|
-
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database =
|
|
31
|
+
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database = ${stringLiteral(database)} AND name = ${stringLiteral(viewName)} AND engine LIKE '%View%'`);
|
|
14
32
|
if (rows.length === 0) {
|
|
15
33
|
throw new Error(`waitForView: ${database}.${viewName} not yet visible`);
|
|
16
34
|
}
|
|
17
35
|
}, RETRY_OPTIONS);
|
|
18
36
|
}
|
|
37
|
+
export async function waitForDictionary(executor, database, dictionaryName) {
|
|
38
|
+
await pRetry(async () => {
|
|
39
|
+
const rows = await executor.query(`SELECT 1 AS x FROM system.dictionaries WHERE database = ${stringLiteral(database)} AND name = ${stringLiteral(dictionaryName)}`);
|
|
40
|
+
if (rows.length === 0) {
|
|
41
|
+
throw new Error(`waitForDictionary: ${database}.${dictionaryName} not yet visible`);
|
|
42
|
+
}
|
|
43
|
+
}, RETRY_OPTIONS);
|
|
44
|
+
}
|
|
19
45
|
export async function waitForColumn(executor, database, tableName, columnName) {
|
|
20
46
|
await pRetry(async () => {
|
|
21
|
-
const rows = await executor.query(`SELECT 1 AS x FROM system.columns WHERE database =
|
|
47
|
+
const rows = await executor.query(`SELECT 1 AS x FROM system.columns WHERE database = ${stringLiteral(database)} AND table = ${stringLiteral(tableName)} AND name = ${stringLiteral(columnName)}`);
|
|
22
48
|
if (rows.length === 0) {
|
|
23
49
|
throw new Error(`waitForColumn: ${database}.${tableName}.${columnName} not yet visible`);
|
|
24
50
|
}
|
|
@@ -40,33 +66,45 @@ export async function waitForRows(executor, sql, predicate, label = 'waitForRows
|
|
|
40
66
|
}
|
|
41
67
|
export async function waitForTableAbsent(executor, database, tableName) {
|
|
42
68
|
await pRetry(async () => {
|
|
43
|
-
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database =
|
|
69
|
+
const rows = await executor.query(`SELECT 1 AS x FROM system.tables WHERE database = ${stringLiteral(database)} AND name = ${stringLiteral(tableName)}`);
|
|
44
70
|
if (rows.length > 0) {
|
|
45
71
|
throw new Error(`waitForTableAbsent: ${database}.${tableName} still present`);
|
|
46
72
|
}
|
|
47
73
|
}, RETRY_OPTIONS);
|
|
48
74
|
}
|
|
49
75
|
/**
|
|
50
|
-
* Parses an operation key like "table:app.users"
|
|
51
|
-
*
|
|
76
|
+
* Parses an operation key like "table:app.users", "table:app.users:column:name",
|
|
77
|
+
* "dictionary:app.users_dict", "view:app.active_users" or
|
|
78
|
+
* "materialized_view:app.events_mv:refresh" into its components. `table` is the
|
|
79
|
+
* object's name in system.tables, which lists views and dictionaries too.
|
|
80
|
+
*
|
|
81
|
+
* Names may contain ':', so the object's name runs to the last occurrence of the
|
|
82
|
+
* suffix its operation type appends; without a known suffix the rest of the key
|
|
83
|
+
* is the name. The database runs to the first '.': the key cannot tell a '.'
|
|
84
|
+
* inside a database name from the separator, so objects in such a database are
|
|
85
|
+
* not found.
|
|
52
86
|
*/
|
|
53
|
-
function parseOperationKey(key) {
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
87
|
+
function parseOperationKey(operationType, key) {
|
|
88
|
+
const keyMatch = key.match(/^(?:table|dictionary|view|materialized_view):([^.]+)\.(.+)$/);
|
|
89
|
+
if (!keyMatch)
|
|
56
90
|
return undefined;
|
|
57
91
|
// biome-ignore lint/style/noNonNullAssertion: capture groups guaranteed by regex match
|
|
58
|
-
const database =
|
|
92
|
+
const database = keyMatch[1];
|
|
59
93
|
// biome-ignore lint/style/noNonNullAssertion: capture groups guaranteed by regex match
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
|
|
94
|
+
const rest = keyMatch[2];
|
|
95
|
+
const suffix = KEY_SUFFIXES.get(operationType);
|
|
96
|
+
const at = suffix === undefined ? -1 : rest.lastIndexOf(suffix);
|
|
97
|
+
if (suffix === undefined || at < 1)
|
|
98
|
+
return { database, table: rest, column: undefined };
|
|
99
|
+
const column = suffix === ':column:' ? rest.slice(at + suffix.length) : undefined;
|
|
100
|
+
return { database, table: rest.slice(0, at), column };
|
|
63
101
|
}
|
|
64
102
|
/**
|
|
65
103
|
* Waits for DDL propagation based on the operation type and key.
|
|
66
104
|
* Called after each DDL statement in the migration execution loop.
|
|
67
105
|
*/
|
|
68
106
|
export async function waitForDDLPropagation(executor, operationType, operationKey) {
|
|
69
|
-
const parsed = parseOperationKey(operationKey);
|
|
107
|
+
const parsed = parseOperationKey(operationType, operationKey);
|
|
70
108
|
if (!parsed)
|
|
71
109
|
return; // database-level ops or unrecognized keys — no wait needed
|
|
72
110
|
switch (operationType) {
|
|
@@ -75,6 +113,8 @@ export async function waitForDDLPropagation(executor, operationType, operationKe
|
|
|
75
113
|
case 'create_view':
|
|
76
114
|
case 'create_materialized_view':
|
|
77
115
|
return waitForView(executor, parsed.database, parsed.table);
|
|
116
|
+
case 'create_dictionary':
|
|
117
|
+
return waitForDictionary(executor, parsed.database, parsed.table);
|
|
78
118
|
case 'alter_table_add_column':
|
|
79
119
|
case 'alter_table_modify_column':
|
|
80
120
|
if (parsed.column) {
|
|
@@ -84,11 +124,18 @@ export async function waitForDDLPropagation(executor, operationType, operationKe
|
|
|
84
124
|
case 'drop_table':
|
|
85
125
|
case 'drop_view':
|
|
86
126
|
case 'drop_materialized_view':
|
|
127
|
+
case 'drop_dictionary':
|
|
87
128
|
return waitForTableAbsent(executor, parsed.database, parsed.table);
|
|
88
129
|
default:
|
|
89
|
-
// alter_table_add_index, alter_table_modify_setting,
|
|
130
|
+
// alter_table_add_index, alter_table_modify_setting,
|
|
131
|
+
// alter_materialized_view_modify_refresh, etc.
|
|
90
132
|
// Wait for the table to exist as a basic sanity check.
|
|
91
133
|
return waitForTable(executor, parsed.database, parsed.table);
|
|
92
134
|
}
|
|
93
135
|
}
|
|
136
|
+
// Object names may contain quotes and backslashes (DDL backtick-quotes them),
|
|
137
|
+
// so the names compared against system tables are escaped string literals.
|
|
138
|
+
function stringLiteral(value) {
|
|
139
|
+
return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
140
|
+
}
|
|
94
141
|
//# sourceMappingURL=ddl-propagation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl-propagation.js","sourceRoot":"","sources":["../src/ddl-propagation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ddl-propagation.js","sourceRoot":"","sources":["../src/ddl-propagation.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,SAAS,CAAA;AAG5B,MAAM,aAAa,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AAEjE,iFAAiF;AACjF,yDAAyD;AACzD,MAAM,YAAY,GAAgC,IAAI,GAAG,CAAiC;IACxF,CAAC,wCAAwC,EAAE,UAAU,CAAC;IACtD,CAAC,wBAAwB,EAAE,UAAU,CAAC;IACtC,CAAC,2BAA2B,EAAE,UAAU,CAAC;IACzC,CAAC,yBAAyB,EAAE,UAAU,CAAC;IACvC,CAAC,2BAA2B,EAAE,iBAAiB,CAAC;IAChD,CAAC,uBAAuB,EAAE,SAAS,CAAC;IACpC,CAAC,wBAAwB,EAAE,SAAS,CAAC;IACrC,CAAC,4BAA4B,EAAE,cAAc,CAAC;IAC9C,CAAC,6BAA6B,EAAE,cAAc,CAAC;IAC/C,CAAC,4BAA4B,EAAE,WAAW,CAAC;IAC3C,CAAC,2BAA2B,EAAE,WAAW,CAAC;IAC1C,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAClC,CAAC,0BAA0B,EAAE,eAAe,CAAC;IAC7C,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;CAC5C,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAA4B,EAC5B,QAAgB,EAChB,SAAiB;IAEjB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC/B,qDAAqD,aAAa,CAAC,QAAQ,CAAC,eAAe,aAAa,CAAC,SAAS,CAAC,EAAE,CACtH,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,iBAAiB,QAAQ,IAAI,SAAS,kBAAkB,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAA4B,EAC5B,QAAgB,EAChB,QAAgB;IAEhB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC/B,qDAAqD,aAAa,CAAC,QAAQ,CAAC,eAAe,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAC9I,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,gBAAgB,QAAQ,IAAI,QAAQ,kBAAkB,CAAC,CAAA;QACzE,CAAC;IACH,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAA4B,EAC5B,QAAgB,EAChB,cAAsB;IAEtB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC/B,2DAA2D,aAAa,CAAC,QAAQ,CAAC,eAAe,aAAa,CAAC,cAAc,CAAC,EAAE,CACjI,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,IAAI,cAAc,kBAAkB,CAAC,CAAA;QACrF,CAAC;IACH,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAA4B,EAC5B,QAAgB,EAChB,SAAiB,EACjB,UAAkB;IAElB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC/B,sDAAsD,aAAa,CAAC,QAAQ,CAAC,gBAAgB,aAAa,CAAC,SAAS,CAAC,eAAe,aAAa,CAAC,UAAU,CAAC,EAAE,CAChK,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,kBAAkB,QAAQ,IAAI,SAAS,IAAI,UAAU,kBAAkB,CACxE,CAAA;QACH,CAAC;IACH,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAA4B,EAC5B,GAAW,EACX,SAAiC,EACjC,KAAK,GAAG,aAAa;IAErB,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAI,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,+BAA+B,CAAC,CAAA;QAC1D,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAA4B,EAC5B,QAAgB,EAChB,SAAiB;IAEjB,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC/B,qDAAqD,aAAa,CAAC,QAAQ,CAAC,eAAe,aAAa,CAAC,SAAS,CAAC,EAAE,CACtH,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,IAAI,SAAS,gBAAgB,CAC7D,CAAA;QACH,CAAC;IACH,CAAC,EAAE,aAAa,CAAC,CAAA;AACnB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CACxB,aAAqB,EACrB,GAAW;IAQX,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAA;IACzF,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC/B,uFAAuF;IACvF,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;IAC7B,uFAAuF;IACvF,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;IAEzB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAC9C,MAAM,EAAE,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IAC/D,IAAI,MAAM,KAAK,SAAS,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACvF,MAAM,MAAM,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACjF,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAA4B,EAC5B,aAAqB,EACrB,YAAoB;IAEpB,MAAM,MAAM,GAAG,iBAAiB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAM,CAAC,2DAA2D;IAE/E,QAAQ,aAAa,EAAE,CAAC;QACtB,KAAK,cAAc;YACjB,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAE9D,KAAK,aAAa,CAAC;QACnB,KAAK,0BAA0B;YAC7B,OAAO,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAE7D,KAAK,mBAAmB;YACtB,OAAO,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAEnE,KAAK,wBAAwB,CAAC;QAC9B,KAAK,2BAA2B;YAC9B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,aAAa,CAClB,QAAQ,EACR,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,MAAM,CACd,CAAA;YACH,CAAC;YACD,OAAM;QAER,KAAK,YAAY,CAAC;QAClB,KAAK,WAAW,CAAC;QACjB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,iBAAiB;YACpB,OAAO,kBAAkB,CACvB,QAAQ,EACR,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,KAAK,CACb,CAAA;QAEH;YACE,qDAAqD;YACrD,+CAA+C;YAC/C,uDAAuD;YACvD,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAChE,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,2EAA2E;AAC3E,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAA;AACjE,CAAC"}
|
package/dist/e2e-testkit.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared E2E test utilities for live ClickHouse tests.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Targets the local test stack (test/infra) unless CLICKHOUSE_* points elsewhere.
|
|
5
|
+
* Never skips: an unreachable server fails the test.
|
|
5
6
|
* Uses ClickHouseExecutor so any package that depends on @chkit/clickhouse can import this.
|
|
6
7
|
*/
|
|
7
8
|
import { type ClickHouseExecutor } from './index.js';
|
|
@@ -11,11 +12,14 @@ export interface LiveEnv {
|
|
|
11
12
|
clickhousePassword: string;
|
|
12
13
|
clickhouseDatabase: string;
|
|
13
14
|
}
|
|
15
|
+
/** The ClickHouse in test/infra/docker-compose.yml, which `infra:up` starts. */
|
|
16
|
+
export declare const LOCAL_STACK_ENV: LiveEnv;
|
|
14
17
|
/**
|
|
15
|
-
* Reads
|
|
16
|
-
*
|
|
18
|
+
* Reads the ClickHouse target from env vars. Without CLICKHOUSE_URL or
|
|
19
|
+
* CLICKHOUSE_HOST, tests run against the local test stack. A remote target
|
|
20
|
+
* must also set CLICKHOUSE_PASSWORD.
|
|
17
21
|
*/
|
|
18
|
-
export declare function
|
|
22
|
+
export declare function getLiveEnv(): LiveEnv;
|
|
19
23
|
/**
|
|
20
24
|
* Creates a ClickHouseExecutor configured for E2E tests from env vars.
|
|
21
25
|
*/
|
|
@@ -30,5 +34,20 @@ export declare function quoteIdent(value: string): string;
|
|
|
30
34
|
export declare function createRunTag(): string;
|
|
31
35
|
export declare function createPrefix(label: string): string;
|
|
32
36
|
export declare function createJournalTableName(label: string): string;
|
|
33
|
-
export
|
|
37
|
+
export interface PollUntilOptions {
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
intervalMs?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Re-reads `read()` until `predicate` accepts its value or `timeoutMs` elapses.
|
|
43
|
+
* Unlike `waitForRows`, running out of time returns the last observed value
|
|
44
|
+
* instead of throwing, so the caller's own `expect` reports the real diff.
|
|
45
|
+
* A read that keeps throwing until the deadline rethrows its last error.
|
|
46
|
+
*
|
|
47
|
+
* Put the whole observation inside `read` (e.g. `SYSTEM RELOAD DICTIONARY`
|
|
48
|
+
* followed by `dictGet`): on multi-replica services each attempt may land on a
|
|
49
|
+
* different replica, so a one-off preparation step can't be relied on.
|
|
50
|
+
*/
|
|
51
|
+
export declare function pollUntil<T>(read: () => Promise<T>, predicate: (value: T) => boolean, options?: PollUntilOptions): Promise<T>;
|
|
52
|
+
export { waitForTable, waitForView, waitForColumn, waitForDictionary, waitForRows, } from './ddl-propagation.js';
|
|
34
53
|
//# sourceMappingURL=e2e-testkit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e2e-testkit.d.ts","sourceRoot":"","sources":["../src/e2e-testkit.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"e2e-testkit.d.ts","sourceRoot":"","sources":["../src/e2e-testkit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAA;AAMnB,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,OAK7B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAepC;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAOnE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAO5E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAMD,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5D;AAMD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,EAChC,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,CAAC,CAAC,CAgBZ;AAID,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,GACZ,MAAM,sBAAsB,CAAA"}
|
package/dist/e2e-testkit.js
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared E2E test utilities for live ClickHouse tests.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Targets the local test stack (test/infra) unless CLICKHOUSE_* points elsewhere.
|
|
5
|
+
* Never skips: an unreachable server fails the test.
|
|
5
6
|
* Uses ClickHouseExecutor so any package that depends on @chkit/clickhouse can import this.
|
|
6
7
|
*/
|
|
8
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
9
|
+
import { quoteIdentifier } from '@chkit/core';
|
|
7
10
|
import { createClickHouseExecutor, createStatelessClickHouseExecutor, } from './index.js';
|
|
11
|
+
/** The ClickHouse in test/infra/docker-compose.yml, which `infra:up` starts. */
|
|
12
|
+
export const LOCAL_STACK_ENV = {
|
|
13
|
+
clickhouseUrl: 'http://localhost:8123',
|
|
14
|
+
clickhouseUser: 'default',
|
|
15
|
+
clickhousePassword: 'chkit-ci',
|
|
16
|
+
clickhouseDatabase: 'default',
|
|
17
|
+
};
|
|
8
18
|
/**
|
|
9
|
-
* Reads
|
|
10
|
-
*
|
|
19
|
+
* Reads the ClickHouse target from env vars. Without CLICKHOUSE_URL or
|
|
20
|
+
* CLICKHOUSE_HOST, tests run against the local test stack. A remote target
|
|
21
|
+
* must also set CLICKHOUSE_PASSWORD.
|
|
11
22
|
*/
|
|
12
|
-
export function
|
|
23
|
+
export function getLiveEnv() {
|
|
13
24
|
const clickhouseHost = process.env.CLICKHOUSE_HOST?.trim();
|
|
14
25
|
const clickhouseUrl = process.env.CLICKHOUSE_URL?.trim() || (clickhouseHost ? `https://${clickhouseHost}` : '');
|
|
26
|
+
if (!clickhouseUrl)
|
|
27
|
+
return LOCAL_STACK_ENV;
|
|
15
28
|
const clickhouseUser = process.env.CLICKHOUSE_USER?.trim() || 'default';
|
|
16
29
|
const clickhousePassword = process.env.CLICKHOUSE_PASSWORD?.trim() || '';
|
|
17
30
|
const clickhouseDatabase = process.env.CLICKHOUSE_DB?.trim() || 'default';
|
|
18
|
-
if (!clickhouseUrl) {
|
|
19
|
-
throw new Error('Missing CLICKHOUSE_URL or CLICKHOUSE_HOST');
|
|
20
|
-
}
|
|
21
31
|
if (!clickhousePassword) {
|
|
22
32
|
throw new Error('Missing CLICKHOUSE_PASSWORD');
|
|
23
33
|
}
|
|
@@ -51,7 +61,7 @@ export function createStatelessLiveExecutor(env) {
|
|
|
51
61
|
});
|
|
52
62
|
}
|
|
53
63
|
export function quoteIdent(value) {
|
|
54
|
-
return
|
|
64
|
+
return quoteIdentifier(value);
|
|
55
65
|
}
|
|
56
66
|
// ---------------------------------------------------------------------------
|
|
57
67
|
// Run tags & naming
|
|
@@ -67,8 +77,36 @@ export function createJournalTableName(label) {
|
|
|
67
77
|
`${Date.now()}_${Math.floor(Math.random() * 100000)}`;
|
|
68
78
|
return `_chkit_migrations_${label}_${runTag}`;
|
|
69
79
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Re-reads `read()` until `predicate` accepts its value or `timeoutMs` elapses.
|
|
82
|
+
* Unlike `waitForRows`, running out of time returns the last observed value
|
|
83
|
+
* instead of throwing, so the caller's own `expect` reports the real diff.
|
|
84
|
+
* A read that keeps throwing until the deadline rethrows its last error.
|
|
85
|
+
*
|
|
86
|
+
* Put the whole observation inside `read` (e.g. `SYSTEM RELOAD DICTIONARY`
|
|
87
|
+
* followed by `dictGet`): on multi-replica services each attempt may land on a
|
|
88
|
+
* different replica, so a one-off preparation step can't be relied on.
|
|
89
|
+
*/
|
|
90
|
+
export async function pollUntil(read, predicate, options = {}) {
|
|
91
|
+
const timeoutMs = options.timeoutMs ?? 30_000;
|
|
92
|
+
const intervalMs = options.intervalMs ?? 500;
|
|
93
|
+
const deadline = Date.now() + timeoutMs;
|
|
94
|
+
for (;;) {
|
|
95
|
+
let value;
|
|
96
|
+
try {
|
|
97
|
+
value = await read();
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (Date.now() >= deadline)
|
|
101
|
+
throw error;
|
|
102
|
+
await sleep(intervalMs);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (predicate(value) || Date.now() >= deadline)
|
|
106
|
+
return value;
|
|
107
|
+
await sleep(intervalMs);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Re-exported from ddl-propagation for test convenience.
|
|
111
|
+
export { waitForTable, waitForView, waitForColumn, waitForDictionary, waitForRows, } from './ddl-propagation.js';
|
|
74
112
|
//# sourceMappingURL=e2e-testkit.js.map
|
package/dist/e2e-testkit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e2e-testkit.js","sourceRoot":"","sources":["../src/e2e-testkit.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"e2e-testkit.js","sourceRoot":"","sources":["../src/e2e-testkit.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,14 @@ export interface ClickHouseInsertParams<T extends Record<string, unknown>> {
|
|
|
15
15
|
table: string;
|
|
16
16
|
values: T[];
|
|
17
17
|
compressed?: boolean;
|
|
18
|
+
/** Per-insert settings, e.g. a stable `insert_deduplication_token`. */
|
|
19
|
+
settings?: ClickHouseSettings;
|
|
20
|
+
/**
|
|
21
|
+
* Explicit INSERT column list as SQL identifiers (quote names that need it).
|
|
22
|
+
* Required to supply EPHEMERAL inputs: without it ClickHouse treats their
|
|
23
|
+
* keys as unknown fields and silently drops them.
|
|
24
|
+
*/
|
|
25
|
+
columns?: string[];
|
|
18
26
|
}
|
|
19
27
|
export interface ClickHouseJsonQueryResult<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
20
28
|
data: T[];
|
|
@@ -30,6 +38,7 @@ export interface ClickHouseJsonQueryResult<T extends Record<string, unknown> = R
|
|
|
30
38
|
};
|
|
31
39
|
query_id?: string;
|
|
32
40
|
}
|
|
41
|
+
export type ObservableSystemTable = 'processes' | 'query_log';
|
|
33
42
|
export interface ClickHouseExecutor {
|
|
34
43
|
command(sql: string): Promise<void>;
|
|
35
44
|
query<T>(sql: string, settings?: ClickHouseSettings): Promise<T[]>;
|
|
@@ -51,10 +60,19 @@ export interface ClickHouseExecutor {
|
|
|
51
60
|
queryStatus(queryId: string, options?: {
|
|
52
61
|
afterTime?: string;
|
|
53
62
|
}): Promise<QueryStatus>;
|
|
63
|
+
/** Optional capability: FROM-clause source for cluster-aware system table polling.
|
|
64
|
+
* Native executors return `clusterAllReplicas(...)` when `clickhouse.cluster` is set.
|
|
65
|
+
* Remote / ObsessionDB executors may omit this and keep local `system.*` tables. */
|
|
66
|
+
systemTableSource?(table: ObservableSystemTable): string;
|
|
54
67
|
close(): Promise<void>;
|
|
55
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the system table expression used for async query observation.
|
|
71
|
+
* Prefers `executor.systemTableSource` when present; otherwise local `system.<table>`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function observableSystemTable(executor: Pick<ClickHouseExecutor, 'systemTableSource'>, table: ObservableSystemTable): string;
|
|
56
74
|
export interface SchemaObjectRef {
|
|
57
|
-
kind: 'table' | 'view' | 'materialized_view';
|
|
75
|
+
kind: 'table' | 'view' | 'materialized_view' | 'dictionary';
|
|
58
76
|
database: string;
|
|
59
77
|
name: string;
|
|
60
78
|
}
|
|
@@ -63,6 +81,7 @@ export interface SystemTableRow {
|
|
|
63
81
|
name: string;
|
|
64
82
|
engine: string;
|
|
65
83
|
create_table_query?: string;
|
|
84
|
+
primary_key?: string;
|
|
66
85
|
}
|
|
67
86
|
export interface SystemColumnRow {
|
|
68
87
|
database: string;
|
|
@@ -106,6 +125,8 @@ type ClickHouseClientOptions = {
|
|
|
106
125
|
};
|
|
107
126
|
};
|
|
108
127
|
export { parseEngineFromCreateTableQuery, parseOrderByFromCreateTableQuery, parsePartitionByFromCreateTableQuery, parsePrimaryKeyFromCreateTableQuery, parseProjectionsFromCreateTableQuery, parseSettingsFromCreateTableQuery, parseTTLFromCreateTableQuery, parseUniqueKeyFromCreateTableQuery, } from './create-table-parser.js';
|
|
128
|
+
export { canonicalizeSqlFragments } from './canonicalize.js';
|
|
129
|
+
export { parseCommentFromCreateDictionaryQuery, parseDictionaryAttributesFromCreateDictionaryQuery, parseDictionaryPrimaryKeyFromCreateDictionaryQuery, parseDictionaryRangeFromCreateDictionaryQuery, parseDictionarySettingsFromCreateDictionaryQuery, parseLayoutFromCreateDictionaryQuery, parseLifetimeFromCreateDictionaryQuery, parseSourceFromCreateDictionaryQuery, type ParsedDictionaryAttribute, } from './create-dictionary-parser.js';
|
|
109
130
|
export declare function inferSchemaKindFromEngine(engine: string): SchemaObjectRef['kind'] | null;
|
|
110
131
|
export declare function normalizeColumnFromSystemRow(row: SystemColumnRow): ColumnDefinition;
|
|
111
132
|
export declare function normalizeIndexFromSystemRow(row: SystemSkippingIndexRow): SkipIndexDefinition;
|
|
@@ -147,7 +168,7 @@ export declare function assertStreamedQuerySucceeded(input: {
|
|
|
147
168
|
query_id: string;
|
|
148
169
|
sql: string | undefined;
|
|
149
170
|
}): void;
|
|
150
|
-
export { waitForColumn, waitForDDLPropagation, waitForTable, waitForTableAbsent, waitForView, } from './ddl-propagation.js';
|
|
171
|
+
export { waitForColumn, waitForDDLPropagation, waitForDictionary, waitForTable, waitForTableAbsent, waitForView, } from './ddl-propagation.js';
|
|
151
172
|
export declare function createStatelessClickHouseClient(config: ClickHouseConfig, clickhouseSettings?: ClickHouseSettings, options?: ClickHouseClientOptions): ClickHouseClient;
|
|
152
173
|
/**
|
|
153
174
|
* Creates a ClickHouse client that sends one session_id with every request.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,SAAS,EACd,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
|
-
import { normalizeSQLFragment, parseCodec, } from '@chkit/core';
|
|
2
|
+
import { isSyntheticEphemeralDefault, normalizeSQLFragment, parseCodec, parseTextIndexParams, normalizeTextIndexSQL, } from '@chkit/core';
|
|
3
3
|
import { ClickHouseLogLevel, createClient } from '@clickhouse/client';
|
|
4
4
|
import { getLogger } from '@logtape/logtape';
|
|
5
5
|
import { parseEngineFromCreateTableQuery, parseOrderByFromCreateTableQuery, parsePartitionByFromCreateTableQuery, parsePrimaryKeyFromCreateTableQuery, parseProjectionsFromCreateTableQuery, parseSettingsFromCreateTableQuery, parseTTLFromCreateTableQuery, parseUniqueKeyFromCreateTableQuery, } from './create-table-parser.js';
|
|
6
6
|
const pkg = createRequire(import.meta.url)('../package.json');
|
|
7
7
|
const CHKIT_APPLICATION_ID = `chkit/${pkg.version}`;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the system table expression used for async query observation.
|
|
10
|
+
* Prefers `executor.systemTableSource` when present; otherwise local `system.<table>`.
|
|
11
|
+
*/
|
|
12
|
+
export function observableSystemTable(executor, table) {
|
|
13
|
+
return executor.systemTableSource?.(table) ?? `system.${table}`;
|
|
14
|
+
}
|
|
8
15
|
export { parseEngineFromCreateTableQuery, parseOrderByFromCreateTableQuery, parsePartitionByFromCreateTableQuery, parsePrimaryKeyFromCreateTableQuery, parseProjectionsFromCreateTableQuery, parseSettingsFromCreateTableQuery, parseTTLFromCreateTableQuery, parseUniqueKeyFromCreateTableQuery, } from './create-table-parser.js';
|
|
16
|
+
export { canonicalizeSqlFragments } from './canonicalize.js';
|
|
17
|
+
export { parseCommentFromCreateDictionaryQuery, parseDictionaryAttributesFromCreateDictionaryQuery, parseDictionaryPrimaryKeyFromCreateDictionaryQuery, parseDictionaryRangeFromCreateDictionaryQuery, parseDictionarySettingsFromCreateDictionaryQuery, parseLayoutFromCreateDictionaryQuery, parseLifetimeFromCreateDictionaryQuery, parseSourceFromCreateDictionaryQuery, } from './create-dictionary-parser.js';
|
|
9
18
|
export function inferSchemaKindFromEngine(engine) {
|
|
10
19
|
if (engine === 'View')
|
|
11
20
|
return 'view';
|
|
12
21
|
if (engine === 'MaterializedView')
|
|
13
22
|
return 'materialized_view';
|
|
14
|
-
if (
|
|
23
|
+
if (engine === 'Dictionary')
|
|
24
|
+
return 'dictionary';
|
|
25
|
+
if (!engine)
|
|
15
26
|
return null;
|
|
16
27
|
return 'table';
|
|
17
28
|
}
|
|
@@ -20,8 +31,17 @@ export function normalizeColumnFromSystemRow(row) {
|
|
|
20
31
|
const type = nullableMatch?.[1] ? nullableMatch[1] : row.type;
|
|
21
32
|
const nullable = Boolean(nullableMatch?.[1]);
|
|
22
33
|
let defaultValue;
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
const defaultKind = row.default_kind;
|
|
35
|
+
if (defaultKind && !['DEFAULT', 'MATERIALIZED', 'ALIAS', 'EPHEMERAL'].includes(defaultKind)) {
|
|
36
|
+
throw new Error(`Unsupported column default kind: ${defaultKind}`);
|
|
37
|
+
}
|
|
38
|
+
if (row.default_expression && defaultKind) {
|
|
39
|
+
// Preserve whitespace inside SQL string literals when pulling expressions.
|
|
40
|
+
defaultValue = row.default_expression.trim();
|
|
41
|
+
}
|
|
42
|
+
// A bare EPHEMERAL column reads back as its synthesized default.
|
|
43
|
+
if (defaultKind === 'EPHEMERAL' && defaultValue !== undefined && isSyntheticEphemeralDefault(String(defaultValue))) {
|
|
44
|
+
defaultValue = undefined;
|
|
25
45
|
}
|
|
26
46
|
const codecSteps = parseCodec(row.compression_codec);
|
|
27
47
|
return {
|
|
@@ -29,6 +49,9 @@ export function normalizeColumnFromSystemRow(row) {
|
|
|
29
49
|
type,
|
|
30
50
|
nullable: nullable || undefined,
|
|
31
51
|
default: defaultValue,
|
|
52
|
+
defaultKind: defaultKind && defaultKind !== 'DEFAULT'
|
|
53
|
+
? defaultKind
|
|
54
|
+
: undefined,
|
|
32
55
|
comment: row.comment?.trim() || undefined,
|
|
33
56
|
codec: codecSteps,
|
|
34
57
|
};
|
|
@@ -42,8 +65,10 @@ function splitArgs(args) {
|
|
|
42
65
|
.filter((value) => !Number.isNaN(value));
|
|
43
66
|
}
|
|
44
67
|
function parseIndexType(value) {
|
|
45
|
-
const match = value.match(/^(\w+)\((
|
|
68
|
+
const match = value.match(/^(\w+)\((.*)\)$/s);
|
|
46
69
|
const baseName = match?.[1] ?? value;
|
|
70
|
+
if (baseName === 'text')
|
|
71
|
+
return { type: 'text', ...parseTextIndexParams(match?.[2] ?? '') };
|
|
47
72
|
const args = splitArgs(match?.[2]);
|
|
48
73
|
switch (baseName) {
|
|
49
74
|
case 'minmax':
|
|
@@ -75,7 +100,7 @@ export function normalizeIndexFromSystemRow(row) {
|
|
|
75
100
|
const parsed = parseIndexType(row.type);
|
|
76
101
|
return {
|
|
77
102
|
name: row.name,
|
|
78
|
-
expression: normalizeSQLFragment(row.expr),
|
|
103
|
+
expression: parsed.type === 'text' ? normalizeTextIndexSQL(row.expr) : normalizeSQLFragment(row.expr),
|
|
79
104
|
granularity: row.granularity,
|
|
80
105
|
...parsed,
|
|
81
106
|
};
|
|
@@ -110,8 +135,8 @@ export function buildIntrospectedTables(tables, columns, indexes) {
|
|
|
110
135
|
return {
|
|
111
136
|
database: row.database,
|
|
112
137
|
name: row.name,
|
|
113
|
-
engine: parseEngineFromCreateTableQuery(row.create_table_query),
|
|
114
|
-
primaryKey: parsePrimaryKeyFromCreateTableQuery(row.create_table_query),
|
|
138
|
+
engine: parseEngineFromCreateTableQuery(row.create_table_query) ?? row.engine,
|
|
139
|
+
primaryKey: parsePrimaryKeyFromCreateTableQuery(row.create_table_query) ?? (row.primary_key || undefined),
|
|
115
140
|
orderBy: parseOrderByFromCreateTableQuery(row.create_table_query),
|
|
116
141
|
uniqueKey: parseUniqueKeyFromCreateTableQuery(row.create_table_query),
|
|
117
142
|
partitionBy: parsePartitionByFromCreateTableQuery(row.create_table_query),
|
|
@@ -258,7 +283,7 @@ export function assertStreamedQuerySucceeded(input) {
|
|
|
258
283
|
sql: input.sql,
|
|
259
284
|
});
|
|
260
285
|
}
|
|
261
|
-
export { waitForColumn, waitForDDLPropagation, waitForTable, waitForTableAbsent, waitForView, } from './ddl-propagation.js';
|
|
286
|
+
export { waitForColumn, waitForDDLPropagation, waitForDictionary, waitForTable, waitForTableAbsent, waitForView, } from './ddl-propagation.js';
|
|
262
287
|
function parseSummaryFromHeaders(headers) {
|
|
263
288
|
const raw = headers['x-clickhouse-summary'];
|
|
264
289
|
if (!raw || typeof raw !== 'string')
|
|
@@ -448,6 +473,8 @@ export function createExecutorWithClient(config, client, options = {}) {
|
|
|
448
473
|
table: params.table,
|
|
449
474
|
values: params.values,
|
|
450
475
|
format: 'JSONEachRow',
|
|
476
|
+
...(isNonEmpty(params.columns) ? { columns: params.columns } : {}),
|
|
477
|
+
...(params.settings ? { clickhouse_settings: params.settings } : {}),
|
|
451
478
|
});
|
|
452
479
|
assertStreamedQuerySucceeded({
|
|
453
480
|
response_headers: result.response_headers,
|
|
@@ -470,10 +497,20 @@ export function createExecutorWithClient(config, client, options = {}) {
|
|
|
470
497
|
}
|
|
471
498
|
return id;
|
|
472
499
|
},
|
|
500
|
+
systemTableSource(table) {
|
|
501
|
+
// `config.cluster` is validated at resolveConfig (assertValidClusterName), so it is
|
|
502
|
+
// safe to interpolate into the single-quoted clusterAllReplicas argument — same
|
|
503
|
+
// contract as onClusterClause. Never guess a default name like 'cluster'.
|
|
504
|
+
if (config.cluster) {
|
|
505
|
+
return `clusterAllReplicas('${config.cluster}', system.${table})`;
|
|
506
|
+
}
|
|
507
|
+
return `system.${table}`;
|
|
508
|
+
},
|
|
473
509
|
async queryStatus(queryId, options) {
|
|
474
510
|
try {
|
|
511
|
+
const processesFrom = observableSystemTable(this, 'processes');
|
|
475
512
|
const running = await client.query({
|
|
476
|
-
query: `SELECT read_rows, read_bytes, written_rows, written_bytes, elapsed FROM
|
|
513
|
+
query: `SELECT read_rows, read_bytes, written_rows, written_bytes, elapsed FROM ${processesFrom} WHERE user = currentUser() AND query_id = {qid:String} SETTINGS skip_unavailable_shards = 1`,
|
|
477
514
|
query_params: { qid: queryId },
|
|
478
515
|
format: 'JSONEachRow',
|
|
479
516
|
});
|
|
@@ -490,9 +527,10 @@ export function createExecutorWithClient(config, client, options = {}) {
|
|
|
490
527
|
};
|
|
491
528
|
}
|
|
492
529
|
const afterTime = options?.afterTime ?? '1970-01-01T00:00:00Z';
|
|
530
|
+
const queryLogFrom = observableSystemTable(this, 'query_log');
|
|
493
531
|
const log = await client.query({
|
|
494
532
|
query: `SELECT type, written_rows, written_bytes, query_duration_ms, exception
|
|
495
|
-
FROM
|
|
533
|
+
FROM ${queryLogFrom}
|
|
496
534
|
WHERE user = currentUser()
|
|
497
535
|
AND query_id = {qid:String}
|
|
498
536
|
AND type IN ('QueryFinish', 'ExceptionWhileProcessing')
|
|
@@ -562,14 +600,14 @@ WHERE is_temporary = 0
|
|
|
562
600
|
const quotedDatabases = databases
|
|
563
601
|
.map((dbName) => `'${dbName.replace(/'/g, "''")}'`)
|
|
564
602
|
.join(', ');
|
|
565
|
-
const tables = await this.query(`SELECT database, name, engine, create_table_query
|
|
603
|
+
const tables = await this.query(`SELECT database, name, engine, create_table_query, primary_key
|
|
566
604
|
FROM system.tables
|
|
567
605
|
WHERE is_temporary = 0
|
|
568
606
|
AND database IN (${quotedDatabases})`);
|
|
569
607
|
const columns = await this.query(`SELECT database, table, name, type, default_kind, default_expression, comment, position, compression_codec
|
|
570
608
|
FROM system.columns
|
|
571
609
|
WHERE database IN (${quotedDatabases})`);
|
|
572
|
-
const indexes = await this.query(`SELECT database, table, name, expr, type, granularity
|
|
610
|
+
const indexes = await this.query(`SELECT database, table, name, expr, type_full AS type, granularity
|
|
573
611
|
FROM system.data_skipping_indices
|
|
574
612
|
WHERE database IN (${quotedDatabases})`);
|
|
575
613
|
return buildIntrospectedTables(tables, columns, indexes);
|
|
@@ -591,4 +629,8 @@ export function createStatelessClickHouseExecutor(config) {
|
|
|
591
629
|
}),
|
|
592
630
|
});
|
|
593
631
|
}
|
|
632
|
+
// @clickhouse/client only accepts a non-empty column list.
|
|
633
|
+
function isNonEmpty(values) {
|
|
634
|
+
return values !== undefined && values.length > 0;
|
|
635
|
+
}
|
|
594
636
|
//# sourceMappingURL=index.js.map
|