@smart-data-engines/sde 0.1.0-dev.0

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.
Files changed (131) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +13 -0
  3. package/README.md +153 -0
  4. package/bin/weather.mjs +32 -0
  5. package/dist/_usage.d.ts +30 -0
  6. package/dist/_usage.js +194 -0
  7. package/dist/_usage.js.map +1 -0
  8. package/dist/bulk.d.ts +9 -0
  9. package/dist/bulk.js +83 -0
  10. package/dist/bulk.js.map +1 -0
  11. package/dist/canonical.d.ts +46 -0
  12. package/dist/canonical.js +150 -0
  13. package/dist/canonical.js.map +1 -0
  14. package/dist/capabilities.d.ts +48 -0
  15. package/dist/capabilities.js +62 -0
  16. package/dist/capabilities.js.map +1 -0
  17. package/dist/cutover.d.ts +36 -0
  18. package/dist/cutover.js +219 -0
  19. package/dist/cutover.js.map +1 -0
  20. package/dist/demo/model.d.ts +28 -0
  21. package/dist/demo/model.js +40 -0
  22. package/dist/demo/model.js.map +1 -0
  23. package/dist/demo/project.d.ts +19 -0
  24. package/dist/demo/project.js +128 -0
  25. package/dist/demo/project.js.map +1 -0
  26. package/dist/demo/weather.d.ts +73 -0
  27. package/dist/demo/weather.js +334 -0
  28. package/dist/demo/weather.js.map +1 -0
  29. package/dist/engines/_clickhouse-connection.d.ts +17 -0
  30. package/dist/engines/_clickhouse-connection.js +182 -0
  31. package/dist/engines/_clickhouse-connection.js.map +1 -0
  32. package/dist/engines/_tls-peer-identity.d.ts +2 -0
  33. package/dist/engines/_tls-peer-identity.js +23 -0
  34. package/dist/engines/_tls-peer-identity.js.map +1 -0
  35. package/dist/engines/_write-fences.d.ts +51 -0
  36. package/dist/engines/_write-fences.js +189 -0
  37. package/dist/engines/_write-fences.js.map +1 -0
  38. package/dist/engines/clickhouse.d.ts +193 -0
  39. package/dist/engines/clickhouse.js +899 -0
  40. package/dist/engines/clickhouse.js.map +1 -0
  41. package/dist/engines/postgres.d.ts +293 -0
  42. package/dist/engines/postgres.js +981 -0
  43. package/dist/engines/postgres.js.map +1 -0
  44. package/dist/errors.d.ts +89 -0
  45. package/dist/errors.js +90 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/frozen-verification.d.ts +26 -0
  48. package/dist/frozen-verification.js +67 -0
  49. package/dist/frozen-verification.js.map +1 -0
  50. package/dist/generation.d.ts +34 -0
  51. package/dist/generation.js +81 -0
  52. package/dist/generation.js.map +1 -0
  53. package/dist/groups.d.ts +17 -0
  54. package/dist/groups.js +66 -0
  55. package/dist/groups.js.map +1 -0
  56. package/dist/hashing.d.ts +68 -0
  57. package/dist/hashing.js +146 -0
  58. package/dist/hashing.js.map +1 -0
  59. package/dist/in-place-index.d.ts +43 -0
  60. package/dist/in-place-index.js +272 -0
  61. package/dist/in-place-index.js.map +1 -0
  62. package/dist/index.d.ts +79 -0
  63. package/dist/index.js +64 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/inspection.d.ts +19 -0
  66. package/dist/inspection.js +31 -0
  67. package/dist/inspection.js.map +1 -0
  68. package/dist/internal.d.ts +42 -0
  69. package/dist/internal.js +56 -0
  70. package/dist/internal.js.map +1 -0
  71. package/dist/layout.d.ts +36 -0
  72. package/dist/layout.js +62 -0
  73. package/dist/layout.js.map +1 -0
  74. package/dist/migration.d.ts +197 -0
  75. package/dist/migration.js +592 -0
  76. package/dist/migration.js.map +1 -0
  77. package/dist/model.d.ts +93 -0
  78. package/dist/model.js +313 -0
  79. package/dist/model.js.map +1 -0
  80. package/dist/physical.d.ts +128 -0
  81. package/dist/physical.js +421 -0
  82. package/dist/physical.js.map +1 -0
  83. package/dist/placement.d.ts +157 -0
  84. package/dist/placement.js +651 -0
  85. package/dist/placement.js.map +1 -0
  86. package/dist/provisioning.d.ts +6 -0
  87. package/dist/provisioning.js +45 -0
  88. package/dist/provisioning.js.map +1 -0
  89. package/dist/query.d.ts +68 -0
  90. package/dist/query.js +340 -0
  91. package/dist/query.js.map +1 -0
  92. package/dist/routing.d.ts +25 -0
  93. package/dist/routing.js +35 -0
  94. package/dist/routing.js.map +1 -0
  95. package/dist/schema.d.ts +110 -0
  96. package/dist/schema.js +337 -0
  97. package/dist/schema.js.map +1 -0
  98. package/dist/session.d.ts +195 -0
  99. package/dist/session.js +870 -0
  100. package/dist/session.js.map +1 -0
  101. package/dist/shapes.d.ts +30 -0
  102. package/dist/shapes.js +112 -0
  103. package/dist/shapes.js.map +1 -0
  104. package/dist/staging.d.ts +29 -0
  105. package/dist/staging.js +214 -0
  106. package/dist/staging.js.map +1 -0
  107. package/dist/telemetry.d.ts +468 -0
  108. package/dist/telemetry.js +872 -0
  109. package/dist/telemetry.js.map +1 -0
  110. package/dist/testing/loader.d.ts +38 -0
  111. package/dist/testing/loader.js +86 -0
  112. package/dist/testing/loader.js.map +1 -0
  113. package/dist/testing/memory.d.ts +131 -0
  114. package/dist/testing/memory.js +311 -0
  115. package/dist/testing/memory.js.map +1 -0
  116. package/dist/timestamp.d.ts +20 -0
  117. package/dist/timestamp.js +89 -0
  118. package/dist/timestamp.js.map +1 -0
  119. package/dist/types.d.ts +79 -0
  120. package/dist/types.js +100 -0
  121. package/dist/types.js.map +1 -0
  122. package/dist/verification.d.ts +41 -0
  123. package/dist/verification.js +169 -0
  124. package/dist/verification.js.map +1 -0
  125. package/dist/watermark.d.ts +103 -0
  126. package/dist/watermark.js +170 -0
  127. package/dist/watermark.js.map +1 -0
  128. package/dist/write-fence.d.ts +58 -0
  129. package/dist/write-fence.js +225 -0
  130. package/dist/write-fence.js.map +1 -0
  131. package/package.json +86 -0
@@ -0,0 +1,51 @@
1
+ import type { Row } from '../session.js';
2
+ import { type FenceBackend, type FenceMetadata } from '../write-fence.js';
3
+ interface PgTransport {
4
+ query(sql: string, values?: readonly unknown[]): Promise<readonly Row[]>;
5
+ transaction(body: () => Promise<void>): Promise<void>;
6
+ busy(): boolean;
7
+ }
8
+ interface ChTransport {
9
+ query(sql: string): Promise<readonly Row[]>;
10
+ command(sql: string): Promise<void>;
11
+ literal(value: unknown): string;
12
+ }
13
+ export declare class PostgresFences implements FenceBackend {
14
+ private readonly transport;
15
+ private readonly quote;
16
+ constructor(transport: PgTransport);
17
+ private idle;
18
+ metadata(table: string): Promise<FenceMetadata>;
19
+ addColumn(table: string): Promise<void>;
20
+ addConstraint(table: string, name: string, expression: string): Promise<void>;
21
+ dropConstraint(table: string, name: string): Promise<void>;
22
+ drain(table: string, options: {
23
+ projectId: string;
24
+ hold: string;
25
+ }): Promise<void>;
26
+ restore(table: string, options: {
27
+ projectId: string;
28
+ hold: string;
29
+ }): Promise<void>;
30
+ }
31
+ export declare class ClickHouseFences implements FenceBackend {
32
+ private readonly transport;
33
+ private readonly quote;
34
+ constructor(transport: ChTransport);
35
+ private table;
36
+ metadata(table: string): Promise<FenceMetadata>;
37
+ addColumn(table: string): Promise<void>;
38
+ addConstraint(table: string, name: string, expression: string): Promise<void>;
39
+ dropConstraint(table: string, name: string): Promise<void>;
40
+ private drainLog;
41
+ drain(table: string, options: {
42
+ projectId: string;
43
+ hold: string;
44
+ }): Promise<void>;
45
+ restore(table: string, options: {
46
+ projectId: string;
47
+ hold: string;
48
+ }): Promise<void>;
49
+ }
50
+ export declare function fenceIO<T>(operation: () => Promise<T>): Promise<T>;
51
+ export {};
@@ -0,0 +1,189 @@
1
+ /** Native fencing DDL for dedicated provisioning connections. No placement decision lives here. */
2
+ import { EngineError, MigrationRefused } from '../errors.js';
3
+ import { QUOTE } from '../schema.js';
4
+ import { DRAIN_TABLE, EPOCH_COLUMN, fenceState } from '../write-fence.js';
5
+ function held(metadata, projectId, hold) {
6
+ const state = fenceState(metadata);
7
+ if (state.projectId !== projectId || !state.holds.includes(hold)) {
8
+ throw new MigrationRefused("the requested project's write barrier is not installed");
9
+ }
10
+ }
11
+ export class PostgresFences {
12
+ transport;
13
+ quote = QUOTE['postgres'];
14
+ constructor(transport) {
15
+ this.transport = transport;
16
+ }
17
+ idle() {
18
+ if (this.transport.busy()) {
19
+ throw new MigrationRefused('write-fence DDL cannot run inside an application transaction');
20
+ }
21
+ }
22
+ async metadata(table) {
23
+ const quoted = this.quote(table);
24
+ const rows = await this.transport.query('SELECT c.oid::text AS identity, c.relkind AS kind, EXISTS (SELECT 1 FROM pg_inherits i ' +
25
+ 'WHERE i.inhrelid=c.oid OR i.inhparent=c.oid) AS inherits FROM pg_class c ' +
26
+ 'WHERE c.oid=to_regclass($1)', [quoted]);
27
+ if (rows.length !== 1)
28
+ throw new EngineError('write-fence table does not exist');
29
+ const row = rows[0];
30
+ if (row['kind'] !== 'r' || row['inherits'] !== false) {
31
+ throw new MigrationRefused('write fences support ordinary PostgreSQL tables without inheritance');
32
+ }
33
+ const columns = await this.transport.query("SELECT a.atttypid='bigint'::regtype AS typed, a.attnotnull AS required, " +
34
+ 'a.attgenerated AS generated, pg_get_expr(d.adbin,d.adrelid) AS expression FROM pg_attribute a ' +
35
+ 'LEFT JOIN pg_attrdef d ON d.adrelid=a.attrelid AND d.adnum=a.attnum ' +
36
+ 'WHERE a.attrelid=to_regclass($1) AND a.attname=$2 AND NOT a.attisdropped', [quoted, EPOCH_COLUMN]);
37
+ const column = columns[0];
38
+ const valid = column !== undefined && column['typed'] === true && column['required'] === true &&
39
+ column['generated'] === '' && (column['expression'] === '0' || column['expression'] === "'0'::bigint");
40
+ const constraints = await this.transport.query("SELECT conname AS name, pg_get_constraintdef(oid) AS expression FROM pg_constraint " +
41
+ "WHERE conrelid=to_regclass($1) AND contype='c'", [quoted]);
42
+ return {
43
+ identity: String(row['identity']), column: valid ? 'valid' : columns.length > 0 ? 'conflict' : 'absent',
44
+ constraints: Object.fromEntries(constraints.map((item) => [String(item['name']), String(item['expression'])])),
45
+ };
46
+ }
47
+ async addColumn(table) {
48
+ this.idle();
49
+ await this.transport.query(`ALTER TABLE ${this.quote(table)} ADD COLUMN IF NOT EXISTS ` +
50
+ `${this.quote(EPOCH_COLUMN)} bigint NOT NULL DEFAULT 0`);
51
+ }
52
+ async addConstraint(table, name, expression) {
53
+ this.idle();
54
+ if (name in (await this.metadata(table)).constraints)
55
+ return;
56
+ const predicate = expression === '1' ? 'true' : expression === '0' ? 'false' : expression;
57
+ await this.transport.query(`ALTER TABLE ${this.quote(table)} ADD CONSTRAINT ${this.quote(name)} ` +
58
+ `CHECK (${predicate}) NOT VALID`);
59
+ }
60
+ async dropConstraint(table, name) {
61
+ this.idle();
62
+ await this.transport.query(`ALTER TABLE ${this.quote(table)} DROP CONSTRAINT IF EXISTS ${this.quote(name)}`);
63
+ }
64
+ async drain(table, options) {
65
+ this.idle();
66
+ await this.transport.transaction(async () => {
67
+ await this.transport.query(`LOCK TABLE ${this.quote(table)} IN SHARE ROW EXCLUSIVE MODE`);
68
+ held(await this.metadata(table), options.projectId, options.hold);
69
+ });
70
+ }
71
+ async restore(table, options) {
72
+ held(await this.metadata(table), options.projectId, options.hold);
73
+ }
74
+ }
75
+ export class ClickHouseFences {
76
+ transport;
77
+ quote = QUOTE['clickhouse'];
78
+ constructor(transport) {
79
+ this.transport = transport;
80
+ }
81
+ table(table) {
82
+ return this.transport.query('SELECT toString(uuid) AS identity, engine, ' +
83
+ 'formatQuery(create_table_query) AS definition FROM system.tables ' +
84
+ 'WHERE database=currentDatabase() AND name=' + this.transport.literal(table));
85
+ }
86
+ async metadata(table) {
87
+ const databases = await this.transport.query('SELECT engine FROM system.databases WHERE name=currentDatabase()');
88
+ if (databases.length !== 1 || databases[0]?.['engine'] !== 'Atomic') {
89
+ throw new MigrationRefused('write fences require a local Atomic ClickHouse database');
90
+ }
91
+ const rows = await this.table(table);
92
+ if (rows.length !== 1) {
93
+ throw new EngineError('write-fence table does not exist or is detached; resume the same operation');
94
+ }
95
+ const row = rows[0];
96
+ if (row['engine'] !== 'MergeTree' && row['engine'] !== 'ReplacingMergeTree') {
97
+ throw new MigrationRefused('write fences support local MergeTree and ReplacingMergeTree tables');
98
+ }
99
+ const columns = await this.transport.query('SELECT type, default_kind, default_expression FROM system.columns ' +
100
+ 'WHERE database=currentDatabase() AND table=' + this.transport.literal(table) +
101
+ ' AND name=' + this.transport.literal(EPOCH_COLUMN));
102
+ const column = columns[0];
103
+ const valid = columns.length === 1 && column?.['type'] === 'Int64' &&
104
+ column['default_kind'] === 'DEFAULT' && column['default_expression'] === '0';
105
+ const constraints = {};
106
+ const pattern = /^\s*CONSTRAINT\s+[`"]?(__sde_f_[A-Za-z0-9_]+)[`"]?\s+CHECK\s+([^\n]+)/gm;
107
+ for (const match of String(row['definition']).matchAll(pattern)) {
108
+ constraints[match[1]] = match[2].trimEnd().replace(/,$/, '');
109
+ }
110
+ return {
111
+ identity: String(row['identity']), column: valid ? 'valid' : columns.length > 0 ? 'conflict' : 'absent',
112
+ constraints,
113
+ };
114
+ }
115
+ async addColumn(table) {
116
+ await this.transport.command(`ALTER TABLE ${this.quote(table)} ADD COLUMN IF NOT EXISTS ` +
117
+ `${this.quote(EPOCH_COLUMN)} Int64 DEFAULT 0`);
118
+ }
119
+ async addConstraint(table, name, expression) {
120
+ await this.transport.command(`ALTER TABLE ${this.quote(table)} ADD CONSTRAINT IF NOT EXISTS ` +
121
+ `${this.quote(name)} CHECK ${expression}`);
122
+ }
123
+ async dropConstraint(table, name) {
124
+ await this.transport.command(`ALTER TABLE ${this.quote(table)} DROP CONSTRAINT IF EXISTS ${this.quote(name)}`);
125
+ }
126
+ async drainLog() {
127
+ await this.transport.command(`CREATE TABLE IF NOT EXISTS ${this.quote(DRAIN_TABLE)} (` +
128
+ 'table_name String, table_uuid UUID, project_id FixedString(32), hold String) ' +
129
+ 'ENGINE=MergeTree ORDER BY (table_uuid, project_id, hold)');
130
+ const columns = await this.transport.query('SELECT name,type FROM system.columns WHERE database=currentDatabase() ' +
131
+ 'AND table=' + this.transport.literal(DRAIN_TABLE) + ' ORDER BY name');
132
+ const actual = columns.map((row) => [row['name'], row['type']]);
133
+ const expected = [['hold', 'String'], ['project_id', 'FixedString(32)'], ['table_name', 'String'], ['table_uuid', 'UUID']];
134
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
135
+ throw new MigrationRefused('the reserved write-fence drain log has an incompatible schema');
136
+ }
137
+ const kinds = await this.transport.query('SELECT engine FROM system.tables WHERE database=currentDatabase() AND name=' +
138
+ this.transport.literal(DRAIN_TABLE));
139
+ if (kinds.length !== 1 || kinds[0]?.['engine'] !== 'MergeTree') {
140
+ throw new MigrationRefused('the reserved write-fence drain log has an incompatible engine');
141
+ }
142
+ }
143
+ async drain(table, options) {
144
+ const metadata = await this.metadata(table);
145
+ held(metadata, options.projectId, options.hold);
146
+ await this.drainLog();
147
+ const values = [table, metadata.identity, options.projectId, options.hold].map(this.transport.literal);
148
+ await this.transport.command(`INSERT INTO ${this.quote(DRAIN_TABLE)} ` +
149
+ '(table_name, table_uuid, project_id, hold) SETTINGS async_insert=0, wait_for_async_insert=1 ' +
150
+ `VALUES (${values.join(', ')})`);
151
+ await this.transport.command(`DETACH TABLE ${this.quote(table)} PERMANENTLY SYNC`);
152
+ await this.transport.command(`ATTACH TABLE ${this.quote(table)}`);
153
+ const after = await this.metadata(table);
154
+ if (after.identity !== metadata.identity)
155
+ throw new EngineError('the write-fence table identity changed while draining it');
156
+ held(after, options.projectId, options.hold);
157
+ }
158
+ async restore(table, options) {
159
+ if ((await this.table(table)).length > 0) {
160
+ held(await this.metadata(table), options.projectId, options.hold);
161
+ return;
162
+ }
163
+ const literal = this.transport.literal;
164
+ const records = await this.transport.query(`SELECT DISTINCT toString(table_uuid) AS identity FROM ${this.quote(DRAIN_TABLE)} ` +
165
+ `WHERE table_name=${literal(table)} AND project_id=${literal(options.projectId)} AND hold=${literal(options.hold)}`);
166
+ const detached = await this.transport.query('SELECT toString(uuid) AS identity FROM system.detached_tables ' +
167
+ `WHERE database=currentDatabase() AND table=${literal(table)} AND is_permanently=1`);
168
+ if (records.length !== 1 || detached.length !== 1 || records[0]?.['identity'] !== detached[0]?.['identity']) {
169
+ throw new MigrationRefused('no matching durable intent for this detached write-fence table');
170
+ }
171
+ await this.transport.command(`ATTACH TABLE ${this.quote(table)}`);
172
+ const metadata = await this.metadata(table);
173
+ if (metadata.identity !== records[0]?.['identity'])
174
+ throw new EngineError('the restored write-fence table has another identity');
175
+ held(metadata, options.projectId, options.hold);
176
+ }
177
+ }
178
+ export async function fenceIO(operation) {
179
+ try {
180
+ return await operation();
181
+ }
182
+ catch (error) {
183
+ if (error instanceof EngineError || error instanceof MigrationRefused)
184
+ throw error;
185
+ const detail = error instanceof Error ? error.message : String(error);
186
+ throw new EngineError('write-fence operation failed; inspect or resume its state: ' + detail);
187
+ }
188
+ }
189
+ //# sourceMappingURL=_write-fences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_write-fences.js","sourceRoot":"","sources":["../../src/engines/_write-fences.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
1
+ import { type ReadColumn, type ReadPlan } from '../query.js';
2
+ import { WriteFence } from '../write-fence.js';
3
+ import type { PhysicalFinding } from '../physical.js';
4
+ import type { PhysicalLayout } from '../placement.js';
5
+ import type { Row } from '../session.js';
6
+ /** Milliseconds, and the same argument as the PostgreSQL adapter's constant of the same name. */
7
+ export declare const CONNECT_TIMEOUT_MS = 10000;
8
+ /**
9
+ * Milliseconds, for the version exchange `connect()` performs.
10
+ *
11
+ * Set to something different from the connect bound on purpose. **Opening is bounded tightly;
12
+ * reading is not, past this exchange** - an analytical query legitimately takes minutes and a
13
+ * library that timed it out would be deciding something about the caller's workload. The handshake
14
+ * is the one exchange this library knows the shape of.
15
+ *
16
+ * The reference implementation reaches the same place through its driver's `send_receive_timeout`,
17
+ * and that is measured rather than assumed: with that bound at 15 seconds, a 23-second and a
18
+ * 24-second query both returned normally, so the bound does not cut a slow query. Here the
19
+ * distinction is structural instead - only the handshake request carries a timeout - which is one
20
+ * fewer thing to be right about.
21
+ */
22
+ export declare const HANDSHAKE_TIMEOUT_MS = 15000;
23
+ export declare class ClickHouseEngine {
24
+ readonly dialect = "clickhouse";
25
+ private readonly usage;
26
+ private readonly target;
27
+ private trust;
28
+ private open;
29
+ private serverVersion;
30
+ constructor(dsn: string);
31
+ /**
32
+ * Ask the server what it is, with a bound on how long that may take.
33
+ *
34
+ * The equivalent of the reference implementation's driver handshake, and it exists for the same
35
+ * measurement: a host that accepts the TCP connection and never answers hung a call for as long
36
+ * as the test would wait. Here the reason is one layer up - the TCP connect succeeds, so a connect
37
+ * bound never fires, and what is left is the wait for a response.
38
+ */
39
+ connect(): Promise<void>;
40
+ close(): Promise<void>;
41
+ /** What the server said it is, or null before `connect()`. Read by nothing; useful in a report. */
42
+ get version(): string | null;
43
+ private ensureOpen;
44
+ /**
45
+ * One HTTP exchange.
46
+ *
47
+ * The handshake has a receive-inactivity default. Later queries retain their unbounded
48
+ * default unless the caller supplies send_receive_timeout. Neither is an absolute execution
49
+ * deadline; server-side max_execution_time can constrain the workload itself.
50
+ */
51
+ private send;
52
+ private query;
53
+ private command;
54
+ /** DDL capability; use a dedicated connection separate from application traffic. */
55
+ writeFence(table: string, options: {
56
+ projectId: string;
57
+ }): WriteFence;
58
+ ensureSchema(layout: PhysicalLayout, options: {
59
+ readonly keys: Readonly<Record<string, readonly string[]>>;
60
+ }): Promise<PhysicalFinding[]>;
61
+ /**
62
+ * Check that what exists is what the map describes, for the reason the PostgreSQL adapter does:
63
+ * `CREATE TABLE IF NOT EXISTS` accepts a table of that name whatever shape it is in.
64
+ *
65
+ * A missing column is refused; an extra one is allowed, because a client may have added one
66
+ * outside SDE and the map has no opinion about it.
67
+ *
68
+ * **Types too, and here they need no normalising at all.** Measured against every type this
69
+ * library renders: `system.columns.type` returns the exact string we wrote, down to the space in
70
+ * `Decimal(12, 2)` and the quotes in `DateTime64(6, 'UTC')`. So the comparison is literal, and
71
+ * it is literal on purpose - a renderer that started emitting a different spelling of the same
72
+ * type would fail this, which is the right way round for a document we sign.
73
+ */
74
+ /** Check existing physical columns without issuing DDL; report the physical design. */
75
+ validateSchema(layout: PhysicalLayout, options?: {
76
+ readonly keys?: Readonly<Record<string, readonly string[]>>;
77
+ }): Promise<PhysicalFinding[]>;
78
+ /**
79
+ * Sort key, partition and data-skipping indexes as the catalogue reports them.
80
+ *
81
+ * The catalogue formats expressions, so they are parsed into names (`parseIdentifierList`)
82
+ * rather than compared with a string we predict: 24.8 leaves `select` bare and quotes `null`, and
83
+ * a formatting rule that moved between releases would turn a correct table into a refusal. An
84
+ * expression the parser does not understand is reported as it stands.
85
+ *
86
+ * `system.tables` is filtered by the login's own table privileges, so a restricted runtime login
87
+ * reads it without a grant. `system.data_skipping_indices` needs an explicit one (measured, 24.8:
88
+ * code 497), so it is read only when a table declares an index, and a login without the grant
89
+ * gets "unverified" rather than a failed session - a check about performance must not become the
90
+ * outage requirement 3.6 forbids. Provisioning refuses on it, since "could not look" is not
91
+ * "looked and agreed".
92
+ */
93
+ private physicalFindings;
94
+ private verifySchema;
95
+ private insertRows;
96
+ insert(table: string, values: Readonly<Row>): Promise<void>;
97
+ /**
98
+ * One row by key, with `FINAL` so a superseded row is never returned.
99
+ *
100
+ * Without `FINAL` a key that has been saved twice returns whichever duplicate the scan reaches
101
+ * first until a merge happens - which is to say, nondeterministically the old value. Paying for
102
+ * `FINAL` on a point read is the cheaper half of that trade.
103
+ */
104
+ /** One HTTP batch, without a cross-block transactional guarantee. */
105
+ insertMany(table: string, rows: readonly Readonly<Row>[]): Promise<void>;
106
+ get(table: string, key: Readonly<Row>): Promise<Row | null>;
107
+ selectRows(table: string, plan: ReadPlan): Promise<Row[]>;
108
+ countRows(table: string, plan: ReadPlan): Promise<bigint>;
109
+ summarizeRows(table: string, plan: ReadPlan, column: ReadColumn): Promise<Readonly<Row>>;
110
+ /**
111
+ * Each table's bytes and its secondary index bytes, from active parts. Numbers only.
112
+ *
113
+ * One statement: `system.tables` says which names exist - readable by a runtime login without
114
+ * any grant, and only for its own tables - and `system.parts` what their active parts occupy,
115
+ * which needs the column grant in `STORAGE_COLUMNS`. An empty table has no parts and reads 0
116
+ * bytes; a missing one is absent, because a missing table is not an empty one.
117
+ */
118
+ storageSizes(tables: readonly string[]): Promise<Map<string, readonly [number, number]>>;
119
+ count(table: string): Promise<number>;
120
+ mapWatermark(): Promise<number | null>;
121
+ recordMapVersion(version: number, options: {
122
+ readonly modelVersion: string;
123
+ }): Promise<void>;
124
+ /**
125
+ * Rows in key order, strictly after one key and up to another inclusive, with `FINAL`.
126
+ *
127
+ * `FINAL` here is not tidiness: without it a key saved twice returns two rows until a merge
128
+ * happens, and the next page starts strictly after that key - so one of the duplicates is read
129
+ * and the other is not, which for a backfill means copying a row this engine considers
130
+ * superseded.
131
+ */
132
+ keyRange(table: string, order: readonly string[], options?: {
133
+ readonly after?: readonly unknown[];
134
+ readonly upto?: readonly unknown[];
135
+ readonly limit?: number;
136
+ }): Promise<Row[]>;
137
+ nthKey(table: string, order: readonly string[], options: {
138
+ readonly position: number;
139
+ }): Promise<unknown[] | null>;
140
+ /**
141
+ * Insert rows. Idempotence here is the table's, not the statement's.
142
+ *
143
+ * There is no `ON CONFLICT` to ask for: a `ReplacingMergeTree` keeps the newest row for a key and
144
+ * collapses the rest at merge time, so recopying a chunk after a crash converges instead of
145
+ * raising. Not the same mechanism as the PostgreSQL adapter's, which is exactly why the live
146
+ * tests run a backfill in every direction rather than in one.
147
+ */
148
+ copyIn(table: string, rows: readonly Row[]): Promise<void>;
149
+ backfillMarker(options: {
150
+ readonly materialization: string;
151
+ readonly entity: string;
152
+ }): Promise<number>;
153
+ recordBackfillMarker(options: {
154
+ readonly materialization: string;
155
+ readonly entity: string;
156
+ readonly rows: number;
157
+ }): Promise<void>;
158
+ /**
159
+ * Refuses. There is no transaction here to give you.
160
+ *
161
+ * A no-op that ran the body would be the friendlier signature and the worse library: the caller
162
+ * would believe a group of writes was atomic, and would find out otherwise from the state of the
163
+ * data rather than from an exception.
164
+ *
165
+ * The way out is not a flag. Declare the atomicity - `atomicWith` on the entity - and the planner
166
+ * is then obliged to place those entities in one group, and one group is one engine, so it will
167
+ * not be this one.
168
+ */
169
+ transaction<T>(_body: () => Promise<T>): Promise<T>;
170
+ }
171
+ /**
172
+ * A SQL literal for one value, and **the only place in this file that escapes a string**.
173
+ *
174
+ * Exported so it can be checked directly, because the alternative is checking it through a server
175
+ * and a server reinterprets escapes inside identifiers: a table name carrying a backslash comes
176
+ * back as a *different* name rather than as a syntax error, so a live test on one cannot isolate
177
+ * this rule. `adapters.test.ts` pins the two characters and also refuses a second escaper anywhere
178
+ * else in this file - which is the class of defect that produced it, found by CodeQL as
179
+ * `js/incomplete-sanitization`.
180
+ *
181
+ * ClickHouse's HTTP interface has no bound parameters in the sense the PostgreSQL protocol does -
182
+ * it has `param_name` substitution, which needs the declared type of every parameter in the query
183
+ * text. So these are rendered, and the rendering is **total**: every kind this library can hold has
184
+ * a branch, and an unknown kind throws rather than falling through to a string. A value that
185
+ * reached a query as an unquoted `[object Object]` would be a syntax error at best.
186
+ */
187
+ /**
188
+ * The columns of `system.parts` a storage measurement reads, and all a runtime login is granted.
189
+ * ClickHouse 24.8 refuses `system.parts` to a login with only table grants; a column grant on these
190
+ * names lets it read the parts of its own tables and no others (measured).
191
+ */
192
+ export declare const STORAGE_COLUMNS: readonly ["database", "table", "active", "bytes_on_disk", "secondary_indices_compressed_bytes", "secondary_indices_marks_bytes"];
193
+ export declare function literal(value: unknown): string;