@uwdata/mosaic-core 0.18.0 → 0.19.1
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/src/Coordinator.d.ts +16 -4
- package/dist/src/Coordinator.d.ts.map +1 -1
- package/dist/src/Coordinator.js +0 -19
- package/dist/src/Coordinator.js.map +1 -1
- package/dist/src/MosaicClient.d.ts.map +1 -1
- package/dist/src/MosaicClient.js +1 -0
- package/dist/src/MosaicClient.js.map +1 -1
- package/dist/src/QueryConsolidator.js +4 -4
- package/dist/src/QueryConsolidator.js.map +1 -1
- package/dist/src/Selection.d.ts +9 -9
- package/dist/src/Selection.d.ts.map +1 -1
- package/dist/src/Selection.js +9 -6
- package/dist/src/Selection.js.map +1 -1
- package/dist/src/SelectionClause.d.ts +55 -25
- package/dist/src/SelectionClause.d.ts.map +1 -1
- package/dist/src/SelectionClause.js +52 -10
- package/dist/src/SelectionClause.js.map +1 -1
- package/dist/src/connectors/wasm.d.ts +3 -0
- package/dist/src/connectors/wasm.d.ts.map +1 -1
- package/dist/src/connectors/wasm.js +5 -2
- package/dist/src/connectors/wasm.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/make-client.d.ts +2 -4
- package/dist/src/make-client.d.ts.map +1 -1
- package/dist/src/make-client.js +1 -1
- package/dist/src/util/decode-ipc.d.ts +1 -1
- package/dist/src/util/decode-ipc.d.ts.map +1 -1
- package/dist/src/util/decode-ipc.js.map +1 -1
- package/dist/src/util/field-info.js.map +1 -1
- package/package.json +6 -6
- package/src/Coordinator.ts +32 -3
- package/src/MosaicClient.ts +1 -0
- package/src/QueryConsolidator.ts +4 -4
- package/src/Selection.ts +12 -9
- package/src/SelectionClause.ts +147 -65
- package/src/connectors/wasm.ts +9 -4
- package/src/index.ts +3 -1
- package/src/make-client.ts +2 -2
- package/src/util/decode-ipc.ts +4 -1
- package/src/util/field-info.ts +3 -3
package/src/SelectionClause.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
1
|
import { isMosaicClient, MosaicClient } from './MosaicClient.js';
|
|
3
|
-
import { type ExprNode, type ExprValue, type ScaleOptions, type ScaleDomain, and, contains, isBetween, isIn, isNotDistinct, literal, or, prefix, regexp_matches, suffix } from '@uwdata/mosaic-sql';
|
|
2
|
+
import { type ExprNode, type ExprValue, type ScaleOptions, type ScaleDomain, and, contains, isBetween, isIn, isNotDistinct, literal, or, prefix, regexp_matches, suffix, listHasAny, listHasAll, lower } from '@uwdata/mosaic-sql';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Selection clause metadata to guide possible query optimizations.
|
|
@@ -26,7 +25,7 @@ export interface PointMetadata extends ClauseMetadata {
|
|
|
26
25
|
* Selection clause metadata indicating text search matching.
|
|
27
26
|
*/
|
|
28
27
|
export interface MatchMetadata extends ClauseMetadata {
|
|
29
|
-
type:
|
|
28
|
+
type: 'match';
|
|
30
29
|
/** The text search matching method used. */
|
|
31
30
|
method?: 'contains' | 'prefix' | 'suffix' | 'regexp' | (string & {});
|
|
32
31
|
}
|
|
@@ -59,9 +58,7 @@ export interface IntervalMetadata extends ClauseMetadata {
|
|
|
59
58
|
bin?: BinMethod
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
export
|
|
63
|
-
reset?: () => void;
|
|
64
|
-
}
|
|
61
|
+
export type ClauseSource = object & { reset?: () => void; };
|
|
65
62
|
|
|
66
63
|
/**
|
|
67
64
|
* A selection clause representing filtering criteria
|
|
@@ -98,6 +95,11 @@ export interface SelectionClause {
|
|
|
98
95
|
meta?: ClauseMetadata;
|
|
99
96
|
}
|
|
100
97
|
|
|
98
|
+
interface PointOptions {
|
|
99
|
+
source: ClauseSource;
|
|
100
|
+
clients?: Set<MosaicClient>;
|
|
101
|
+
}
|
|
102
|
+
|
|
101
103
|
/**
|
|
102
104
|
* Generate a selection clause for a single selected point value.
|
|
103
105
|
* @param field The table column or expression to select.
|
|
@@ -109,13 +111,13 @@ export interface SelectionClause {
|
|
|
109
111
|
* cross-filtering contexts.
|
|
110
112
|
* @returns The generated selection clause.
|
|
111
113
|
*/
|
|
112
|
-
export function clausePoint(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
export function clausePoint(
|
|
115
|
+
field: ExprValue,
|
|
116
|
+
value: unknown, {
|
|
117
|
+
source,
|
|
118
|
+
clients = isMosaicClient(source) ? new Set([source]) : undefined
|
|
119
|
+
}: PointOptions
|
|
120
|
+
): SelectionClause {
|
|
119
121
|
const predicate: ExprNode | null = value !== undefined
|
|
120
122
|
? isIn(field, [literal(value)])
|
|
121
123
|
: null;
|
|
@@ -140,15 +142,16 @@ export function clausePoint(field: ExprValue, value: unknown, {
|
|
|
140
142
|
* cross-filtering contexts.
|
|
141
143
|
* @returns The generated selection clause.
|
|
142
144
|
*/
|
|
143
|
-
export function clausePoints(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
145
|
+
export function clausePoints(
|
|
146
|
+
fields: ExprValue[],
|
|
147
|
+
value: unknown[][] | null | undefined,
|
|
148
|
+
{
|
|
149
|
+
source,
|
|
150
|
+
clients = isMosaicClient(source) ? new Set([source]) : undefined
|
|
151
|
+
}: PointOptions
|
|
152
|
+
): SelectionClause {
|
|
150
153
|
let predicate: ExprNode | null = null;
|
|
151
|
-
if (value) {
|
|
154
|
+
if (value?.length) {
|
|
152
155
|
const clauses = value.length && fields.length === 1
|
|
153
156
|
? [isIn(fields[0], value.map(v => literal(v[0])))]
|
|
154
157
|
: value.map(v => and(v.map((_, i) => isNotDistinct(fields[i], literal(_)))));
|
|
@@ -165,6 +168,14 @@ export function clausePoints(fields: ExprValue[], value: unknown[][] | null | un
|
|
|
165
168
|
};
|
|
166
169
|
}
|
|
167
170
|
|
|
171
|
+
/** Interval selection clause options. */
|
|
172
|
+
interface IntervalOptions {
|
|
173
|
+
source: ClauseSource;
|
|
174
|
+
clients?: Set<MosaicClient>;
|
|
175
|
+
bin?: BinMethod;
|
|
176
|
+
pixelSize?: number;
|
|
177
|
+
}
|
|
178
|
+
|
|
168
179
|
/**
|
|
169
180
|
* Generate a selection clause for a selected 1D interval.
|
|
170
181
|
* @param field The table column or expression to select.
|
|
@@ -179,19 +190,17 @@ export function clausePoints(fields: ExprValue[], value: unknown[][] | null | un
|
|
|
179
190
|
* @param options.pixelSize The interactive pixel size.
|
|
180
191
|
* @returns The generated selection clause.
|
|
181
192
|
*/
|
|
182
|
-
export function clauseInterval(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
scale?: ScaleOptions
|
|
192
|
-
|
|
193
|
-
pixelSize?: number;
|
|
194
|
-
}): SelectionClause {
|
|
193
|
+
export function clauseInterval(
|
|
194
|
+
field: ExprValue,
|
|
195
|
+
value: ScaleDomain | null | undefined,
|
|
196
|
+
{
|
|
197
|
+
source,
|
|
198
|
+
clients = isMosaicClient(source) ? new Set([source]) : undefined,
|
|
199
|
+
bin,
|
|
200
|
+
scale,
|
|
201
|
+
pixelSize = 1
|
|
202
|
+
}: IntervalOptions & { scale?: ScaleOptions }
|
|
203
|
+
): SelectionClause {
|
|
195
204
|
const predicate = value != null ? isBetween(field, value) : null;
|
|
196
205
|
const meta: IntervalMetadata = {
|
|
197
206
|
type: 'interval',
|
|
@@ -217,19 +226,17 @@ export function clauseInterval(field: ExprValue, value: ScaleDomain | null | und
|
|
|
217
226
|
* @param options.pixelSize The interactive pixel size.
|
|
218
227
|
* @returns The generated selection clause.
|
|
219
228
|
*/
|
|
220
|
-
export function clauseIntervals(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
scales?: ScaleOptions[]
|
|
230
|
-
|
|
231
|
-
pixelSize?: number;
|
|
232
|
-
}): SelectionClause {
|
|
229
|
+
export function clauseIntervals(
|
|
230
|
+
fields: ExprValue[],
|
|
231
|
+
value: ScaleDomain[] | null | undefined,
|
|
232
|
+
{
|
|
233
|
+
source,
|
|
234
|
+
clients = isMosaicClient(source) ? new Set([source]) : undefined,
|
|
235
|
+
bin,
|
|
236
|
+
scales = [],
|
|
237
|
+
pixelSize = 1
|
|
238
|
+
}: IntervalOptions & { scales?: ScaleOptions[] }
|
|
239
|
+
): SelectionClause {
|
|
233
240
|
const predicate = value != null
|
|
234
241
|
? and(fields.map((f, i) => isBetween(f, value[i])))
|
|
235
242
|
: null;
|
|
@@ -242,34 +249,109 @@ export function clauseIntervals(fields: ExprValue[], value: ScaleDomain[] | null
|
|
|
242
249
|
return { meta, source, clients, value, predicate };
|
|
243
250
|
}
|
|
244
251
|
|
|
252
|
+
const identity = (x: string | ExprNode) => x;
|
|
253
|
+
|
|
245
254
|
const MATCH_METHODS = { contains, prefix, suffix, regexp: regexp_matches };
|
|
246
255
|
|
|
247
256
|
/** Text search matching methods. */
|
|
248
|
-
export type MatchMethod = keyof typeof MATCH_METHODS
|
|
257
|
+
export type MatchMethod = keyof typeof MATCH_METHODS;
|
|
258
|
+
|
|
259
|
+
/** Text matching selection clause options. */
|
|
260
|
+
export interface MatchOptions {
|
|
261
|
+
source: ClauseSource;
|
|
262
|
+
clients?: Set<MosaicClient>;
|
|
263
|
+
method?: MatchMethod;
|
|
264
|
+
caseSensitive?: boolean;
|
|
265
|
+
}
|
|
249
266
|
|
|
250
267
|
/**
|
|
251
|
-
* Generate a selection clause for text search matching.
|
|
252
|
-
* @param field The table column or expression to
|
|
268
|
+
* Generate a selection clause for text search matching over a single column.
|
|
269
|
+
* @param field The table column or expression to match.
|
|
253
270
|
* @param value The selected text search query string.
|
|
254
271
|
* @param options Additional clause properties.
|
|
255
272
|
* @param options.source The source component generating this clause.
|
|
256
|
-
* @param options.clients
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* @param options.
|
|
273
|
+
* @param options.clients Mosaic clients associated with this clause.
|
|
274
|
+
* These clients are not filtered by this clause in cross-filtering contexts.
|
|
275
|
+
* @param options.method The text matching method to use, default `'contains'`.
|
|
276
|
+
* @param options.caseSensitive Flag for case sensitive matching, default `false`.
|
|
260
277
|
* @returns The generated selection clause.
|
|
261
278
|
*/
|
|
262
|
-
export function clauseMatch(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
279
|
+
export function clauseMatch(
|
|
280
|
+
field: string | ExprNode,
|
|
281
|
+
value: string | null | undefined,
|
|
282
|
+
{
|
|
283
|
+
source,
|
|
284
|
+
clients = undefined,
|
|
285
|
+
method = 'contains',
|
|
286
|
+
caseSensitive = false
|
|
287
|
+
}: MatchOptions
|
|
288
|
+
): SelectionClause {
|
|
271
289
|
const fn = MATCH_METHODS[method as keyof typeof MATCH_METHODS];
|
|
272
|
-
const
|
|
290
|
+
const transform = caseSensitive ? identity: lower;
|
|
291
|
+
const predicate = value ? fn(transform(field), transform(literal(value))) : null;
|
|
273
292
|
const meta: MatchMetadata = { type: 'match', method };
|
|
274
293
|
return { meta, source, clients, value, predicate };
|
|
275
|
-
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Generate a selection clause for text search matching over multiple columns.
|
|
298
|
+
* A match will succeed if any field successfully matches.
|
|
299
|
+
* @param fields The table columns or expressions to match.
|
|
300
|
+
* @param value The selected text search query string.
|
|
301
|
+
* @param options Additional clause properties.
|
|
302
|
+
* @param options.source The source component generating this clause.
|
|
303
|
+
* @param options.clients Mosaic clients associated with this clause.
|
|
304
|
+
* These clients are not filtered by this clause in cross-filtering contexts.
|
|
305
|
+
* @param options.method The text matching method to use, default `'contains'`.
|
|
306
|
+
* @param options.caseSensitive Flag for case sensitive matching, default `false`.
|
|
307
|
+
* @returns The generated selection clause.
|
|
308
|
+
*/
|
|
309
|
+
export function clauseMatchAny(
|
|
310
|
+
fields: (string | ExprNode)[],
|
|
311
|
+
value: string | null,
|
|
312
|
+
{
|
|
313
|
+
source,
|
|
314
|
+
clients = undefined,
|
|
315
|
+
method = 'contains',
|
|
316
|
+
caseSensitive = false
|
|
317
|
+
}: MatchOptions
|
|
318
|
+
): SelectionClause {
|
|
319
|
+
value = value || null;
|
|
320
|
+
const fn = MATCH_METHODS[method];
|
|
321
|
+
const transform = caseSensitive ? identity : lower;
|
|
322
|
+
const query = transform(literal(value));
|
|
323
|
+
const predicate = value
|
|
324
|
+
? or(fields.flatMap(field => value ? fn(transform(field), query) : []))
|
|
325
|
+
: null;
|
|
326
|
+
const meta: MatchMetadata = { type: 'match', method };
|
|
327
|
+
return { meta, source, clients, value, predicate };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Generate a selection clause for a single selected point value in a list.
|
|
332
|
+
* @param field The table column or expression to select, which must be a list.
|
|
333
|
+
* @param value The selected value.
|
|
334
|
+
* @param options Additional clause properties.
|
|
335
|
+
* @param options.source The source component generating this clause.
|
|
336
|
+
* @param options.clients The Mosaic clients associated
|
|
337
|
+
* with this clause. These clients are not filtered by this clause in
|
|
338
|
+
* cross-filtering contexts.
|
|
339
|
+
* @returns The generated selection clause.
|
|
340
|
+
*/
|
|
341
|
+
export function clauseList(
|
|
342
|
+
field: ExprValue,
|
|
343
|
+
value: unknown,
|
|
344
|
+
{
|
|
345
|
+
source,
|
|
346
|
+
clients = isMosaicClient(source) ? new Set([source]) : undefined,
|
|
347
|
+
listMatch = 'any'
|
|
348
|
+
}: {
|
|
349
|
+
source: ClauseSource;
|
|
350
|
+
clients?: Set<MosaicClient>;
|
|
351
|
+
listMatch?: 'any' | 'all';
|
|
352
|
+
}
|
|
353
|
+
): SelectionClause {
|
|
354
|
+
const listFn = listMatch === 'all' ? listHasAll : listHasAny;
|
|
355
|
+
const predicate = value !== undefined ? listFn(field, literal(value)) : null;
|
|
356
|
+
return { source, clients, value, predicate };
|
|
357
|
+
}
|
package/src/connectors/wasm.ts
CHANGED
|
@@ -15,6 +15,8 @@ interface DuckDBWASMConnectorOptions extends DuckDBWASMOptions {
|
|
|
15
15
|
duckdb?: duckdb.AsyncDuckDB;
|
|
16
16
|
/** Optional pre-existing DuckDB-WASM connection. */
|
|
17
17
|
connection?: duckdb.AsyncDuckDBConnection;
|
|
18
|
+
/** Optional database config. */
|
|
19
|
+
config?: duckdb.DuckDBConfig;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
@@ -34,6 +36,7 @@ export class DuckDBWASMConnector implements Connector {
|
|
|
34
36
|
public _options: DuckDBWASMOptions;
|
|
35
37
|
public _db?: duckdb.AsyncDuckDB;
|
|
36
38
|
public _con?: duckdb.AsyncDuckDBConnection;
|
|
39
|
+
public _config?: duckdb.DuckDBConfig;
|
|
37
40
|
public _loadPromise?: Promise<unknown>;
|
|
38
41
|
|
|
39
42
|
/**
|
|
@@ -41,11 +44,12 @@ export class DuckDBWASMConnector implements Connector {
|
|
|
41
44
|
* @param options Connector options.
|
|
42
45
|
*/
|
|
43
46
|
constructor(options: DuckDBWASMConnectorOptions = {}) {
|
|
44
|
-
const { ipc, duckdb, connection, ...opts } = options;
|
|
47
|
+
const { ipc, duckdb, connection, config, ...opts } = options;
|
|
45
48
|
this._ipc = ipc;
|
|
46
49
|
this._options = opts;
|
|
47
50
|
this._db = duckdb;
|
|
48
51
|
this._con = connection;
|
|
52
|
+
this._config = config;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
/**
|
|
@@ -87,7 +91,7 @@ export class DuckDBWASMConnector implements Connector {
|
|
|
87
91
|
* @param con The DuckDB-WASM connection.
|
|
88
92
|
* @param query The SQL query to run.
|
|
89
93
|
*/
|
|
90
|
-
function getArrowIPC(con: duckdb.AsyncDuckDBConnection, query: string): Promise<
|
|
94
|
+
function getArrowIPC(con: duckdb.AsyncDuckDBConnection, query: string): Promise<Uint8Array> {
|
|
91
95
|
return new Promise((resolve, reject) => {
|
|
92
96
|
con.useUnsafe(async (bindings, conn) => {
|
|
93
97
|
try {
|
|
@@ -113,6 +117,7 @@ function connect(c: DuckDBWASMConnector): Promise<unknown> {
|
|
|
113
117
|
c._db
|
|
114
118
|
? Promise.resolve(c._db)
|
|
115
119
|
: initDatabase(c._options).then(result => c._db = result))
|
|
120
|
+
.then(db => c._config != undefined ? db.open(c._config).then(() => db) : db)
|
|
116
121
|
.then(db => db.connect())
|
|
117
122
|
.then(result => c._con = result);
|
|
118
123
|
}
|
|
@@ -135,7 +140,7 @@ async function initDatabase({
|
|
|
135
140
|
new Blob([`importScripts("${bundle.mainWorker}");`], {type: 'text/javascript'})
|
|
136
141
|
);
|
|
137
142
|
|
|
138
|
-
// Instantiate the
|
|
143
|
+
// Instantiate the asynchronous version of DuckDB-wasm
|
|
139
144
|
const worker = new Worker(worker_url);
|
|
140
145
|
const logger = log ? new duckdb.ConsoleLogger() : new duckdb.VoidLogger();
|
|
141
146
|
const db = new duckdb.AsyncDuckDB(logger, worker);
|
|
@@ -143,4 +148,4 @@ async function initDatabase({
|
|
|
143
148
|
URL.revokeObjectURL(worker_url);
|
|
144
149
|
|
|
145
150
|
return db;
|
|
146
|
-
}
|
|
151
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -17,9 +17,11 @@ export { DuckDBWASMConnector } from './connectors/wasm.js';
|
|
|
17
17
|
export {
|
|
18
18
|
clauseInterval,
|
|
19
19
|
clauseIntervals,
|
|
20
|
+
clauseList,
|
|
20
21
|
clausePoint,
|
|
21
22
|
clausePoints,
|
|
22
|
-
clauseMatch
|
|
23
|
+
clauseMatch,
|
|
24
|
+
clauseMatchAny
|
|
23
25
|
} from './SelectionClause.js';
|
|
24
26
|
|
|
25
27
|
export { decodeIPC } from './util/decode-ipc.js';
|
package/src/make-client.ts
CHANGED
|
@@ -30,9 +30,9 @@ export interface MakeClientOptions {
|
|
|
30
30
|
* Make a new client with the given options, and connect the client to the
|
|
31
31
|
* provided coordinator.
|
|
32
32
|
* @param options The options for making the client.
|
|
33
|
-
* @returns The resulting client
|
|
33
|
+
* @returns The resulting client.
|
|
34
34
|
*/
|
|
35
|
-
export function makeClient(options: MakeClientOptions): MosaicClient
|
|
35
|
+
export function makeClient(options: MakeClientOptions): MosaicClient {
|
|
36
36
|
const {
|
|
37
37
|
coordinator = defaultCoordinator(),
|
|
38
38
|
...clientOptions
|
package/src/util/decode-ipc.ts
CHANGED
|
@@ -10,6 +10,9 @@ import { tableFromIPC } from '@uwdata/flechette';
|
|
|
10
10
|
* values to JS Date objects.
|
|
11
11
|
* @returns A table instance.
|
|
12
12
|
*/
|
|
13
|
-
export function decodeIPC(
|
|
13
|
+
export function decodeIPC(
|
|
14
|
+
data: ArrayBufferLike | Uint8Array,
|
|
15
|
+
options: ExtractionOptions = { useDate: true }
|
|
16
|
+
): Table {
|
|
14
17
|
return tableFromIPC(data, options);
|
|
15
18
|
}
|
package/src/util/field-info.ts
CHANGED
|
@@ -66,7 +66,7 @@ async function getFieldInfo(mc: Coordinator, { table, column, stats }: FieldInfo
|
|
|
66
66
|
.groupby(isNode(column) && isAggregateExpression(column) ? sql`ALL` : []);
|
|
67
67
|
|
|
68
68
|
const [desc] = Array.from(
|
|
69
|
-
await mc.query(Query.describe(q))
|
|
69
|
+
await mc.query(Query.describe(q))
|
|
70
70
|
) as ColumnDescription[];
|
|
71
71
|
const info: FieldInfo = {
|
|
72
72
|
table,
|
|
@@ -83,7 +83,7 @@ async function getFieldInfo(mc: Coordinator, { table, column, stats }: FieldInfo
|
|
|
83
83
|
const [result] = await mc.query(
|
|
84
84
|
summarize({ table, column, stats }),
|
|
85
85
|
{ persist: true }
|
|
86
|
-
)
|
|
86
|
+
);
|
|
87
87
|
|
|
88
88
|
// extract summary stats, copy to field info, and return
|
|
89
89
|
return Object.assign(info, result);
|
|
@@ -97,7 +97,7 @@ async function getFieldInfo(mc: Coordinator, { table, column, stats }: FieldInfo
|
|
|
97
97
|
*/
|
|
98
98
|
async function getTableInfo(mc: Coordinator, table: string): Promise<FieldInfo[]> {
|
|
99
99
|
const result = Array.from(
|
|
100
|
-
await mc.query(`DESCRIBE ${asTableRef(table)}`)
|
|
100
|
+
await mc.query(`DESCRIBE ${asTableRef(table)}`)
|
|
101
101
|
) as ColumnDescription[];
|
|
102
102
|
return result.map(desc => ({
|
|
103
103
|
table,
|