@malloydata/db-duckdb 0.0.195-dev241003204905 → 0.0.195
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/duckdb.spec.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
const duckdb_common_1 = require("./duckdb_common");
|
|
26
26
|
const duckdb_connection_1 = require("./duckdb_connection");
|
|
27
|
+
const malloy_1 = require("@malloydata/malloy");
|
|
27
28
|
const test_1 = require("@malloydata/malloy/test");
|
|
28
29
|
const [describe] = (0, test_1.describeIfDatabaseAvailable)(['duckdb']);
|
|
29
30
|
/*
|
|
@@ -69,17 +70,17 @@ describe('DuckDBConnection', () => {
|
|
|
69
70
|
expect(runRawSQL).toHaveBeenCalledTimes(2);
|
|
70
71
|
});
|
|
71
72
|
it('caches sql schema', async () => {
|
|
72
|
-
await connection.
|
|
73
|
+
await connection.fetchSchemaForSQLStruct(SQL_BLOCK_1, {});
|
|
73
74
|
expect(runRawSQL).toHaveBeenCalledTimes(1);
|
|
74
75
|
await new Promise(resolve => setTimeout(resolve));
|
|
75
|
-
await connection.
|
|
76
|
+
await connection.fetchSchemaForSQLStruct(SQL_BLOCK_1, {});
|
|
76
77
|
expect(runRawSQL).toHaveBeenCalledTimes(1);
|
|
77
78
|
});
|
|
78
79
|
it('refreshes sql schema', async () => {
|
|
79
|
-
await connection.
|
|
80
|
+
await connection.fetchSchemaForSQLStruct(SQL_BLOCK_2, {});
|
|
80
81
|
expect(runRawSQL).toHaveBeenCalledTimes(1);
|
|
81
82
|
await new Promise(resolve => setTimeout(resolve));
|
|
82
|
-
await connection.
|
|
83
|
+
await connection.fetchSchemaForSQLStruct(SQL_BLOCK_2, {
|
|
83
84
|
refreshTimestamp: Date.now() + 10,
|
|
84
85
|
});
|
|
85
86
|
expect(runRawSQL).toHaveBeenCalledTimes(2);
|
|
@@ -106,24 +107,12 @@ describe('DuckDBConnection', () => {
|
|
|
106
107
|
const structDef = makeStructDef();
|
|
107
108
|
connection.fillStructDefFromTypeMap(structDef, { test: ARRAY_SCHEMA });
|
|
108
109
|
expect(structDef.fields[0]).toEqual({
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
'type': 'nested',
|
|
116
|
-
},
|
|
117
|
-
'structSource': {
|
|
118
|
-
'type': 'nested',
|
|
119
|
-
},
|
|
120
|
-
'fields': [
|
|
121
|
-
{
|
|
122
|
-
'name': 'value',
|
|
123
|
-
'type': 'number',
|
|
124
|
-
'numberType': 'integer',
|
|
125
|
-
},
|
|
126
|
-
],
|
|
110
|
+
name: 'test',
|
|
111
|
+
type: 'array',
|
|
112
|
+
elementTypeDef: intTyp,
|
|
113
|
+
join: 'many',
|
|
114
|
+
dialect: 'duckdb',
|
|
115
|
+
fields: (0, malloy_1.arrayEachFields)({ type: 'number', numberType: 'integer' }),
|
|
127
116
|
});
|
|
128
117
|
});
|
|
129
118
|
it('parses inline', () => {
|
|
@@ -131,29 +120,13 @@ describe('DuckDBConnection', () => {
|
|
|
131
120
|
connection.fillStructDefFromTypeMap(structDef, { test: INLINE_SCHEMA });
|
|
132
121
|
expect(structDef.fields[0]).toEqual({
|
|
133
122
|
'name': 'test',
|
|
134
|
-
'type': '
|
|
123
|
+
'type': 'record',
|
|
135
124
|
'dialect': 'duckdb',
|
|
136
|
-
'
|
|
137
|
-
'type': 'inline',
|
|
138
|
-
},
|
|
139
|
-
'structSource': {
|
|
140
|
-
'type': 'inline',
|
|
141
|
-
},
|
|
125
|
+
'join': 'one',
|
|
142
126
|
'fields': [
|
|
143
|
-
{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
'numberType': 'float',
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
'name': 'b',
|
|
150
|
-
'type': 'number',
|
|
151
|
-
'numberType': 'integer',
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
'name': 'c',
|
|
155
|
-
'type': 'string',
|
|
156
|
-
},
|
|
127
|
+
{ 'name': 'a', ...dblType },
|
|
128
|
+
{ 'name': 'b', ...intTyp },
|
|
129
|
+
{ 'name': 'c', ...strTyp },
|
|
157
130
|
],
|
|
158
131
|
});
|
|
159
132
|
});
|
|
@@ -162,14 +135,10 @@ describe('DuckDBConnection', () => {
|
|
|
162
135
|
connection.fillStructDefFromTypeMap(structDef, { test: NESTED_SCHEMA });
|
|
163
136
|
expect(structDef.fields[0]).toEqual({
|
|
164
137
|
'name': 'test',
|
|
165
|
-
'type': '
|
|
138
|
+
'type': 'array',
|
|
139
|
+
'elementTypeDef': { type: 'record_element' },
|
|
166
140
|
'dialect': 'duckdb',
|
|
167
|
-
'
|
|
168
|
-
'fieldName': 'test',
|
|
169
|
-
'isArray': false,
|
|
170
|
-
'type': 'nested',
|
|
171
|
-
},
|
|
172
|
-
'structSource': { 'type': 'nested' },
|
|
141
|
+
'join': 'many',
|
|
173
142
|
'fields': [
|
|
174
143
|
{ 'name': 'a', 'numberType': 'float', 'type': 'number' },
|
|
175
144
|
{ 'name': 'b', 'numberType': 'integer', 'type': 'number' },
|
|
@@ -195,14 +164,11 @@ describe('DuckDBConnection', () => {
|
|
|
195
164
|
*/
|
|
196
165
|
const makeStructDef = () => {
|
|
197
166
|
return {
|
|
198
|
-
type: '
|
|
167
|
+
type: 'table',
|
|
199
168
|
name: 'test',
|
|
200
169
|
dialect: 'duckdb',
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
type: 'basetable',
|
|
204
|
-
connectionName: 'duckdb',
|
|
205
|
-
},
|
|
170
|
+
tablePath: 'test',
|
|
171
|
+
connection: 'duckdb',
|
|
206
172
|
fields: [],
|
|
207
173
|
};
|
|
208
174
|
};
|
|
@@ -212,8 +178,11 @@ const makeStructDef = () => {
|
|
|
212
178
|
//
|
|
213
179
|
// Uses string value for table
|
|
214
180
|
const SQL_BLOCK_1 = {
|
|
215
|
-
type: '
|
|
181
|
+
type: 'sql_select',
|
|
216
182
|
name: 'block1',
|
|
183
|
+
dialect: 'duckdb',
|
|
184
|
+
connection: 'duckdb',
|
|
185
|
+
fields: [],
|
|
217
186
|
selectStr: `
|
|
218
187
|
SELECT
|
|
219
188
|
created_at,
|
|
@@ -230,8 +199,11 @@ FROM "inventory_items.parquet"
|
|
|
230
199
|
};
|
|
231
200
|
// Uses read_parquet() for table
|
|
232
201
|
const SQL_BLOCK_2 = {
|
|
233
|
-
type: '
|
|
202
|
+
type: 'sql_select',
|
|
234
203
|
name: 'block2',
|
|
204
|
+
dialect: 'duckdb',
|
|
205
|
+
connection: 'duckdb',
|
|
206
|
+
fields: [],
|
|
235
207
|
selectStr: `
|
|
236
208
|
SELECT
|
|
237
209
|
created_at,
|
|
@@ -255,4 +227,7 @@ const ARRAY_SCHEMA = 'integer[]';
|
|
|
255
227
|
const INLINE_SCHEMA = 'STRUCT(a double, b integer, c varchar(60))';
|
|
256
228
|
// STRUCT(....)[] is nested
|
|
257
229
|
const NESTED_SCHEMA = 'STRUCT(a double, b integer, c varchar(60))[]';
|
|
230
|
+
const intTyp = { type: 'number', numberType: 'integer' };
|
|
231
|
+
const strTyp = { type: 'string' };
|
|
232
|
+
const dblType = { type: 'number', numberType: 'float' };
|
|
258
233
|
//# sourceMappingURL=duckdb.spec.js.map
|
package/dist/duckdb_common.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MalloyQueryData, PersistSQLResults, PooledConnection, QueryDataRow, QueryOptionsReader, QueryRunStats, RunSQLOptions, StreamingConnection, StructDef, TestableConnection, SQLSourceDef, TableSourceDef } from '@malloydata/malloy';
|
|
2
2
|
import { BaseConnection } from '@malloydata/malloy/connection';
|
|
3
3
|
export interface DuckDBQueryOptions {
|
|
4
4
|
rowLimit: number;
|
|
@@ -9,8 +9,6 @@ export declare abstract class DuckDBCommon extends BaseConnection implements Tes
|
|
|
9
9
|
protected motherDuckToken: string | undefined;
|
|
10
10
|
private readonly dialect;
|
|
11
11
|
static DEFAULT_QUERY_OPTIONS: DuckDBQueryOptions;
|
|
12
|
-
private schemaCache;
|
|
13
|
-
private sqlSchemaCache;
|
|
14
12
|
readonly name: string;
|
|
15
13
|
get dialectName(): string;
|
|
16
14
|
protected readQueryOptions(): DuckDBQueryOptions;
|
|
@@ -28,7 +26,7 @@ export declare abstract class DuckDBCommon extends BaseConnection implements Tes
|
|
|
28
26
|
}>;
|
|
29
27
|
runSQL(sql: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
|
|
30
28
|
abstract runSQLStream(sql: string, options: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
|
|
31
|
-
|
|
29
|
+
fetchSelectSchema(sqlRef: SQLSourceDef): Promise<SQLSourceDef | string>;
|
|
32
30
|
estimateQueryCost(_: string): Promise<QueryRunStats>;
|
|
33
31
|
/**
|
|
34
32
|
* Split's a structs columns declaration into individual columns
|
|
@@ -46,18 +44,7 @@ export declare abstract class DuckDBCommon extends BaseConnection implements Tes
|
|
|
46
44
|
[name: string]: string;
|
|
47
45
|
}): void;
|
|
48
46
|
private schemaFromQuery;
|
|
49
|
-
|
|
50
|
-
structDef: StructDef;
|
|
51
|
-
error?: undefined;
|
|
52
|
-
} | {
|
|
53
|
-
error: string;
|
|
54
|
-
structDef?: undefined;
|
|
55
|
-
}>;
|
|
56
|
-
fetchSchemaForTables(tables: Record<string, string>, { refreshTimestamp }: FetchSchemaOptions): Promise<{
|
|
57
|
-
schemas: Record<string, StructDef>;
|
|
58
|
-
errors: Record<string, string>;
|
|
59
|
-
}>;
|
|
60
|
-
private getTableSchema;
|
|
47
|
+
fetchTableSchema(tableKey: string, tablePath: string): Promise<TableSourceDef>;
|
|
61
48
|
canStream(): this is StreamingConnection;
|
|
62
49
|
test(): Promise<void>;
|
|
63
50
|
abstract createHash(sqlCommand: string): Promise<string>;
|
package/dist/duckdb_common.js
CHANGED
|
@@ -34,7 +34,7 @@ const unquoteName = (name) => {
|
|
|
34
34
|
};
|
|
35
35
|
class DuckDBCommon extends connection_1.BaseConnection {
|
|
36
36
|
get dialectName() {
|
|
37
|
-
return
|
|
37
|
+
return this.dialect.name;
|
|
38
38
|
}
|
|
39
39
|
readQueryOptions() {
|
|
40
40
|
const options = DuckDBCommon.DEFAULT_QUERY_OPTIONS;
|
|
@@ -55,8 +55,6 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
55
55
|
this.queryOptions = queryOptions;
|
|
56
56
|
this.isMotherDuck = false;
|
|
57
57
|
this.dialect = new malloy_1.DuckDBDialect();
|
|
58
|
-
this.schemaCache = new Map();
|
|
59
|
-
this.sqlSchemaCache = new Map();
|
|
60
58
|
this.name = 'duckdb_common';
|
|
61
59
|
}
|
|
62
60
|
isPool() {
|
|
@@ -85,24 +83,10 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
85
83
|
}
|
|
86
84
|
return { rows: result, totalRows: result.length };
|
|
87
85
|
}
|
|
88
|
-
async
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
name: sqlRef.name,
|
|
93
|
-
structSource: {
|
|
94
|
-
type: 'sql',
|
|
95
|
-
method: 'subquery',
|
|
96
|
-
sqlBlock: sqlRef,
|
|
97
|
-
},
|
|
98
|
-
structRelationship: {
|
|
99
|
-
type: 'basetable',
|
|
100
|
-
connectionName: this.name,
|
|
101
|
-
},
|
|
102
|
-
fields: [],
|
|
103
|
-
};
|
|
104
|
-
await this.schemaFromQuery(`DESCRIBE SELECT * FROM (${sqlRef.selectStr})`, structDef);
|
|
105
|
-
return structDef;
|
|
86
|
+
async fetchSelectSchema(sqlRef) {
|
|
87
|
+
const sqlDef = { ...sqlRef };
|
|
88
|
+
await this.schemaFromQuery(`DESCRIBE SELECT * FROM (${sqlRef.selectStr})`, sqlDef);
|
|
89
|
+
return sqlDef;
|
|
106
90
|
}
|
|
107
91
|
async estimateQueryCost(_) {
|
|
108
92
|
return {};
|
|
@@ -168,8 +152,6 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
168
152
|
let duckDBType = typeMap[fieldName];
|
|
169
153
|
// Remove quotes from field name
|
|
170
154
|
const name = unquoteName(fieldName);
|
|
171
|
-
// Remove DECIMAL(x,y) precision to simplify lookup
|
|
172
|
-
duckDBType = duckDBType.replace(/^DECIMAL\(\d+,\d+\)/g, 'DECIMAL');
|
|
173
155
|
let malloyType = this.dialect.sqlTypeToMalloyType(duckDBType);
|
|
174
156
|
const arrayMatch = duckDBType.match(/(?<duckDBType>.*)\[\]$/);
|
|
175
157
|
if (arrayMatch && arrayMatch.groups) {
|
|
@@ -178,22 +160,23 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
178
160
|
const structMatch = duckDBType.match(/^STRUCT\((?<fields>.*)\)$/);
|
|
179
161
|
if (structMatch && structMatch.groups) {
|
|
180
162
|
const newTypeMap = this.stringToTypeMap(structMatch.groups['fields']);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
163
|
+
let innerStructDef;
|
|
164
|
+
const structhead = { name, dialect: this.dialectName, fields: [] };
|
|
165
|
+
if (arrayMatch) {
|
|
166
|
+
innerStructDef = {
|
|
167
|
+
type: 'array',
|
|
168
|
+
elementTypeDef: { type: 'record_element' },
|
|
169
|
+
join: 'many',
|
|
170
|
+
...structhead,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
innerStructDef = {
|
|
175
|
+
type: 'record',
|
|
176
|
+
join: 'one',
|
|
177
|
+
...structhead,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
197
180
|
this.fillStructDefFromTypeMap(innerStructDef, newTypeMap);
|
|
198
181
|
structDef.fields.push(innerStructDef);
|
|
199
182
|
}
|
|
@@ -201,30 +184,17 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
201
184
|
if (arrayMatch) {
|
|
202
185
|
malloyType = this.dialect.sqlTypeToMalloyType(duckDBType);
|
|
203
186
|
const innerStructDef = {
|
|
204
|
-
type: '
|
|
187
|
+
type: 'array',
|
|
188
|
+
elementTypeDef: malloyType,
|
|
205
189
|
name,
|
|
206
190
|
dialect: this.dialectName,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
type: 'nested',
|
|
210
|
-
fieldName: name,
|
|
211
|
-
isArray: true,
|
|
212
|
-
},
|
|
213
|
-
fields: [{ ...malloyType, name: 'value' }],
|
|
191
|
+
join: 'many',
|
|
192
|
+
fields: (0, malloy_1.arrayEachFields)(malloyType),
|
|
214
193
|
};
|
|
215
194
|
structDef.fields.push(innerStructDef);
|
|
216
195
|
}
|
|
217
196
|
else {
|
|
218
|
-
|
|
219
|
-
structDef.fields.push({ ...malloyType, name });
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
structDef.fields.push({
|
|
223
|
-
type: 'sql native',
|
|
224
|
-
rawType: duckDBType.toLowerCase(),
|
|
225
|
-
name,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
197
|
+
structDef.fields.push({ ...malloyType, name });
|
|
228
198
|
}
|
|
229
199
|
}
|
|
230
200
|
}
|
|
@@ -237,64 +207,13 @@ class DuckDBCommon extends connection_1.BaseConnection {
|
|
|
237
207
|
}
|
|
238
208
|
this.fillStructDefFromTypeMap(structDef, typeMap);
|
|
239
209
|
}
|
|
240
|
-
async
|
|
241
|
-
const key = sqlRef.name;
|
|
242
|
-
let inCache = this.sqlSchemaCache.get(key);
|
|
243
|
-
if (!inCache ||
|
|
244
|
-
(refreshTimestamp && refreshTimestamp > inCache.timestamp)) {
|
|
245
|
-
const timestamp = refreshTimestamp !== null && refreshTimestamp !== void 0 ? refreshTimestamp : Date.now();
|
|
246
|
-
try {
|
|
247
|
-
inCache = {
|
|
248
|
-
structDef: await this.getSQLBlockSchema(sqlRef),
|
|
249
|
-
timestamp,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
catch (error) {
|
|
253
|
-
inCache = { error: error.message, timestamp };
|
|
254
|
-
}
|
|
255
|
-
this.sqlSchemaCache.set(key, inCache);
|
|
256
|
-
}
|
|
257
|
-
return inCache;
|
|
258
|
-
}
|
|
259
|
-
async fetchSchemaForTables(tables, { refreshTimestamp }) {
|
|
260
|
-
const schemas = {};
|
|
261
|
-
const errors = {};
|
|
262
|
-
for (const tableKey in tables) {
|
|
263
|
-
let inCache = this.schemaCache.get(tableKey);
|
|
264
|
-
if (!inCache ||
|
|
265
|
-
(refreshTimestamp && refreshTimestamp > inCache.timestamp)) {
|
|
266
|
-
const timestamp = refreshTimestamp !== null && refreshTimestamp !== void 0 ? refreshTimestamp : Date.now();
|
|
267
|
-
const tablePath = tables[tableKey];
|
|
268
|
-
try {
|
|
269
|
-
inCache = {
|
|
270
|
-
schema: await this.getTableSchema(tableKey, tablePath),
|
|
271
|
-
timestamp,
|
|
272
|
-
};
|
|
273
|
-
this.schemaCache.set(tableKey, inCache);
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
inCache = { error: error.message, timestamp };
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
if (inCache.schema !== undefined) {
|
|
280
|
-
schemas[tableKey] = inCache.schema;
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
errors[tableKey] = inCache.error || 'Unknown schema fetch error';
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return { schemas, errors };
|
|
287
|
-
}
|
|
288
|
-
async getTableSchema(tableKey, tablePath) {
|
|
210
|
+
async fetchTableSchema(tableKey, tablePath) {
|
|
289
211
|
const structDef = {
|
|
290
|
-
type: '
|
|
212
|
+
type: 'table',
|
|
291
213
|
name: tableKey,
|
|
292
|
-
dialect:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
type: 'basetable',
|
|
296
|
-
connectionName: this.name,
|
|
297
|
-
},
|
|
214
|
+
dialect: this.dialectName,
|
|
215
|
+
tablePath,
|
|
216
|
+
connection: this.name,
|
|
298
217
|
fields: [],
|
|
299
218
|
};
|
|
300
219
|
const quotedTablePath = tablePath.match(/[:*/]/)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as duckdb from '@duckdb/duckdb-wasm';
|
|
2
|
-
import { FetchSchemaOptions, QueryDataRow, QueryOptionsReader, RunSQLOptions,
|
|
2
|
+
import { FetchSchemaOptions, QueryDataRow, QueryOptionsReader, RunSQLOptions, SQLSourceDef, ConnectionConfig, TableSourceDef } from '@malloydata/malloy';
|
|
3
3
|
import { StructRow } from 'apache-arrow';
|
|
4
4
|
import { DuckDBCommon } from './duckdb_common';
|
|
5
5
|
/**
|
|
@@ -53,15 +53,15 @@ export declare abstract class DuckDBWASMConnection extends DuckDBCommon {
|
|
|
53
53
|
}>;
|
|
54
54
|
runSQLStream(sql: string, { rowLimit, abortSignal }?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
|
|
55
55
|
private findTables;
|
|
56
|
-
|
|
57
|
-
structDef:
|
|
56
|
+
fetchSchemaForSQLStruct(sqlRef: SQLSourceDef, options: FetchSchemaOptions): Promise<{
|
|
57
|
+
structDef: SQLSourceDef;
|
|
58
58
|
error?: undefined;
|
|
59
59
|
} | {
|
|
60
60
|
error: string;
|
|
61
61
|
structDef?: undefined;
|
|
62
62
|
}>;
|
|
63
63
|
fetchSchemaForTables(missing: Record<string, string>, options: FetchSchemaOptions): Promise<{
|
|
64
|
-
schemas: Record<string,
|
|
64
|
+
schemas: Record<string, TableSourceDef>;
|
|
65
65
|
errors: Record<string, string>;
|
|
66
66
|
}>;
|
|
67
67
|
close(): Promise<void>;
|
|
@@ -336,7 +336,7 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
336
336
|
await this.remoteFileStatus[tablePath];
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
-
async
|
|
339
|
+
async fetchSchemaForSQLStruct(sqlRef, options) {
|
|
340
340
|
const tables = [];
|
|
341
341
|
for (const match of sqlRef.selectStr.matchAll(TABLE_MATCH)) {
|
|
342
342
|
tables.push(match[2] || match[3]);
|
|
@@ -345,7 +345,7 @@ class DuckDBWASMConnection extends duckdb_common_1.DuckDBCommon {
|
|
|
345
345
|
tables.push(match[2] || match[3]);
|
|
346
346
|
}
|
|
347
347
|
await this.findTables(tables, options);
|
|
348
|
-
return super.
|
|
348
|
+
return super.fetchSchemaForSQLStruct(sqlRef, options);
|
|
349
349
|
}
|
|
350
350
|
async fetchSchemaForTables(missing, options) {
|
|
351
351
|
const tables = Object.values(missing);
|
|
@@ -39,10 +39,8 @@ describe('DuckDBWasmConnection', () => {
|
|
|
39
39
|
});
|
|
40
40
|
beforeEach(() => {
|
|
41
41
|
jest
|
|
42
|
-
.spyOn(duckdb_common_1.DuckDBCommon.prototype, '
|
|
43
|
-
.mockResolvedValue(
|
|
44
|
-
error: 'mocked',
|
|
45
|
-
});
|
|
42
|
+
.spyOn(duckdb_common_1.DuckDBCommon.prototype, 'fetchSelectSchema')
|
|
43
|
+
.mockResolvedValue('mocked');
|
|
46
44
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
45
|
findTables = jest.spyOn(connection, 'findTables');
|
|
48
46
|
});
|
|
@@ -50,7 +48,7 @@ describe('DuckDBWasmConnection', () => {
|
|
|
50
48
|
jest.resetAllMocks();
|
|
51
49
|
});
|
|
52
50
|
it('finds simple tables in SQL', async () => {
|
|
53
|
-
await connection.
|
|
51
|
+
await connection.fetchSchemaForSQLStruct({
|
|
54
52
|
selectStr: `
|
|
55
53
|
SELECT
|
|
56
54
|
created_at,
|
|
@@ -68,7 +66,7 @@ FROM "inventory_items.parquet"
|
|
|
68
66
|
expect(findTables).toHaveBeenCalledWith(['order_items.parquet', 'inventory_items.parquet'], {});
|
|
69
67
|
});
|
|
70
68
|
it('finds table functions in SQL', async () => {
|
|
71
|
-
await connection.
|
|
69
|
+
await connection.fetchSchemaForSQLStruct({
|
|
72
70
|
selectStr: `
|
|
73
71
|
SELECT
|
|
74
72
|
created_at,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/db-duckdb",
|
|
3
|
-
"version": "0.0.195
|
|
3
|
+
"version": "0.0.195",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@duckdb/duckdb-wasm": "1.28.1-dev242.0",
|
|
44
|
-
"@malloydata/malloy": "^0.0.195
|
|
44
|
+
"@malloydata/malloy": "^0.0.195",
|
|
45
45
|
"@motherduck/wasm-client": "^0.6.3",
|
|
46
46
|
"apache-arrow": "^16.0.0",
|
|
47
47
|
"duckdb": "1.0.0",
|