@malloydata/malloy 0.0.362 → 0.0.363
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/api/core.js +21 -3
- package/dist/api/foundation/compile.js +20 -0
- package/dist/api/foundation/runtime.d.ts +16 -4
- package/dist/api/foundation/runtime.js +22 -4
- package/dist/api/foundation/types.d.ts +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/lang/ast/index.d.ts +5 -0
- package/dist/lang/ast/index.js +5 -0
- package/dist/lang/ast/source-elements/named-source.js +4 -0
- package/dist/lang/ast/source-elements/typed-source.d.ts +23 -0
- package/dist/lang/ast/source-elements/typed-source.js +133 -0
- package/dist/lang/ast/source-elements/virtual-source.d.ts +10 -0
- package/dist/lang/ast/source-elements/virtual-source.js +47 -0
- package/dist/lang/ast/source-properties/user-type-shape.d.ts +29 -0
- package/dist/lang/ast/source-properties/user-type-shape.js +100 -0
- package/dist/lang/ast/source-query-elements/sq-reference.js +1 -1
- package/dist/lang/ast/source-query-elements/sq-typed-source.d.ts +18 -0
- package/dist/lang/ast/source-query-elements/sq-typed-source.js +39 -0
- package/dist/lang/ast/statements/define-user-type.d.ts +28 -0
- package/dist/lang/ast/statements/define-user-type.js +82 -0
- package/dist/lang/ast/types/malloy-element.js +14 -6
- package/dist/lang/lib/Malloy/MalloyLexer.d.ts +146 -144
- package/dist/lang/lib/Malloy/MalloyLexer.js +1408 -1391
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +491 -307
- package/dist/lang/lib/Malloy/MalloyParser.js +7907 -6680
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +186 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +117 -0
- package/dist/lang/malloy-to-ast.d.ts +17 -0
- package/dist/lang/malloy-to-ast.js +118 -0
- package/dist/lang/parse-log.d.ts +12 -1
- package/dist/lang/parse-malloy.d.ts +6 -1
- package/dist/lang/parse-malloy.js +17 -1
- package/dist/lang/parse-tree-walkers/find-external-references.d.ts +4 -0
- package/dist/lang/parse-tree-walkers/find-external-references.js +10 -0
- package/dist/lang/test/test-translator.d.ts +2 -1
- package/dist/lang/test/test-translator.js +10 -0
- package/dist/lang/translate-response.d.ts +6 -1
- package/dist/lang/translate-response.js +3 -1
- package/dist/model/malloy_types.d.ts +23 -2
- package/dist/model/malloy_types.js +12 -2
- package/dist/model/query_model_impl.js +3 -0
- package/dist/model/query_query.js +11 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/dist/api/core.js
CHANGED
|
@@ -167,7 +167,8 @@ function getSchemaFields(schema) {
|
|
|
167
167
|
return fields;
|
|
168
168
|
}
|
|
169
169
|
function compilerNeedsToUpdate(compilerNeeds) {
|
|
170
|
-
var _a, _b, _c, _d, _e, _f;
|
|
170
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
171
|
+
var _l;
|
|
171
172
|
const update = {
|
|
172
173
|
urls: {},
|
|
173
174
|
tables: {},
|
|
@@ -200,10 +201,22 @@ function compilerNeedsToUpdate(compilerNeeds) {
|
|
|
200
201
|
update.translations[translation.url] = modelDef;
|
|
201
202
|
}
|
|
202
203
|
}
|
|
204
|
+
for (const connection of (_g = compilerNeeds.connections) !== null && _g !== void 0 ? _g : []) {
|
|
205
|
+
if (connection.dialect) {
|
|
206
|
+
(_h = update.connectionDialects) !== null && _h !== void 0 ? _h : (update.connectionDialects = {});
|
|
207
|
+
update.connectionDialects[connection.name] = connection.dialect;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
(_j = update.errors) !== null && _j !== void 0 ? _j : (update.errors = {});
|
|
211
|
+
(_k = (_l = update.errors).connectionDialects) !== null && _k !== void 0 ? _k : (_l.connectionDialects = {});
|
|
212
|
+
update.errors.connectionDialects[connection.name] =
|
|
213
|
+
`Connection '${connection.name}' not found`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
203
216
|
}
|
|
204
217
|
return update;
|
|
205
218
|
}
|
|
206
|
-
function convertCompilerNeeds(compileSQL, urls, tables) {
|
|
219
|
+
function convertCompilerNeeds(compileSQL, urls, tables, connectionDialects) {
|
|
207
220
|
var _a, _b, _c;
|
|
208
221
|
const compilerNeeds = {};
|
|
209
222
|
const neededConnections = new Set();
|
|
@@ -235,6 +248,11 @@ function convertCompilerNeeds(compileSQL, urls, tables) {
|
|
|
235
248
|
neededConnections.add(connectionName);
|
|
236
249
|
}
|
|
237
250
|
}
|
|
251
|
+
if (connectionDialects !== undefined) {
|
|
252
|
+
for (const connName in connectionDialects) {
|
|
253
|
+
neededConnections.add(connectionDialects[connName].connectionName);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
238
256
|
if (neededConnections.size > 0) {
|
|
239
257
|
compilerNeeds.connections = Array.from(neededConnections).map(c => ({
|
|
240
258
|
name: c,
|
|
@@ -350,7 +368,7 @@ function _statedCompileModel(state) {
|
|
|
350
368
|
}
|
|
351
369
|
}
|
|
352
370
|
else {
|
|
353
|
-
const compilerNeeds = convertCompilerNeeds(result.compileSQL, result.urls, result.tables);
|
|
371
|
+
const compilerNeeds = convertCompilerNeeds(result.compileSQL, result.urls, result.tables, result.connectionDialects);
|
|
354
372
|
const timingInfo = timer.stop();
|
|
355
373
|
return { compilerNeeds, logs: result.problems, timingInfo };
|
|
356
374
|
}
|
|
@@ -273,6 +273,26 @@ class Malloy {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
+
if (result.connectionDialects) {
|
|
277
|
+
for (const connName in result.connectionDialects) {
|
|
278
|
+
const { connectionName } = result.connectionDialects[connName];
|
|
279
|
+
try {
|
|
280
|
+
const connection = await connections.lookupConnection(connectionName);
|
|
281
|
+
translator.update({
|
|
282
|
+
connectionDialects: { [connName]: connection.dialectName },
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
translator.update({
|
|
287
|
+
errors: {
|
|
288
|
+
connectionDialects: {
|
|
289
|
+
[connName]: error.toString(),
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
276
296
|
if (result.compileSQL) {
|
|
277
297
|
// Unlike other requests, these do not come in batches
|
|
278
298
|
const toCompile = result.compileSQL;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Connection, LookupConnection } from '../../connection/types';
|
|
2
2
|
import type { URLReader, EventStream } from '../../runtime_types';
|
|
3
|
-
import type { ModelDef, Query as InternalQuery, SearchIndexResult, SearchValueMapResult, QueryRunStats, BuildManifest } from '../../model';
|
|
3
|
+
import type { ModelDef, Query as InternalQuery, SearchIndexResult, SearchValueMapResult, QueryRunStats, BuildManifest, VirtualMap } from '../../model';
|
|
4
4
|
import type { Dialect } from '../../dialect';
|
|
5
5
|
import type { RunSQLOptions } from '../../run_sql_options';
|
|
6
6
|
import type { CacheManager } from './cache';
|
|
@@ -40,11 +40,13 @@ export declare class Runtime {
|
|
|
40
40
|
private _eventStream;
|
|
41
41
|
private _cacheManager;
|
|
42
42
|
private _buildManifest;
|
|
43
|
-
|
|
43
|
+
private _virtualMap;
|
|
44
|
+
constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, virtualMap, }: {
|
|
44
45
|
urlReader?: URLReader;
|
|
45
46
|
eventStream?: EventStream;
|
|
46
47
|
cacheManager?: CacheManager;
|
|
47
48
|
buildManifest?: BuildManifest;
|
|
49
|
+
virtualMap?: VirtualMap;
|
|
48
50
|
} & Connectionable);
|
|
49
51
|
/**
|
|
50
52
|
* @return The `CacheManager` for this runtime instance.
|
|
@@ -70,6 +72,14 @@ export declare class Runtime {
|
|
|
70
72
|
*/
|
|
71
73
|
get buildManifest(): BuildManifest | undefined;
|
|
72
74
|
set buildManifest(manifest: BuildManifest | undefined);
|
|
75
|
+
/**
|
|
76
|
+
* The virtual map for virtual source resolution.
|
|
77
|
+
* When set, compiled queries automatically resolve virtual sources
|
|
78
|
+
* against this map. Can be overridden per-query via
|
|
79
|
+
* CompileQueryOptions.virtualMap.
|
|
80
|
+
*/
|
|
81
|
+
get virtualMap(): VirtualMap | undefined;
|
|
82
|
+
set virtualMap(map: VirtualMap | undefined);
|
|
73
83
|
/**
|
|
74
84
|
* Load a Malloy model by URL or contents.
|
|
75
85
|
*
|
|
@@ -142,19 +152,21 @@ export declare class Runtime {
|
|
|
142
152
|
}
|
|
143
153
|
export declare class ConnectionRuntime extends Runtime {
|
|
144
154
|
readonly rawConnections: Connection[];
|
|
145
|
-
constructor({ urlReader, connections, buildManifest, }: {
|
|
155
|
+
constructor({ urlReader, connections, buildManifest, virtualMap, }: {
|
|
146
156
|
urlReader?: URLReader;
|
|
147
157
|
connections: Connection[];
|
|
148
158
|
buildManifest?: BuildManifest;
|
|
159
|
+
virtualMap?: VirtualMap;
|
|
149
160
|
});
|
|
150
161
|
}
|
|
151
162
|
export declare class SingleConnectionRuntime<T extends Connection = Connection> extends Runtime {
|
|
152
163
|
readonly connection: T;
|
|
153
|
-
constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, }: {
|
|
164
|
+
constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, virtualMap, }: {
|
|
154
165
|
urlReader?: URLReader;
|
|
155
166
|
eventStream?: EventStream;
|
|
156
167
|
cacheManager?: CacheManager;
|
|
157
168
|
buildManifest?: BuildManifest;
|
|
169
|
+
virtualMap?: VirtualMap;
|
|
158
170
|
connection: T;
|
|
159
171
|
});
|
|
160
172
|
get supportsNesting(): boolean;
|
|
@@ -46,7 +46,7 @@ class FluentState {
|
|
|
46
46
|
* An environment for compiling and running Malloy queries.
|
|
47
47
|
*/
|
|
48
48
|
class Runtime {
|
|
49
|
-
constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, }) {
|
|
49
|
+
constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, virtualMap, }) {
|
|
50
50
|
this.isTestRuntime = false;
|
|
51
51
|
if (connections === undefined) {
|
|
52
52
|
if (connection === undefined) {
|
|
@@ -64,6 +64,7 @@ class Runtime {
|
|
|
64
64
|
this._eventStream = eventStream;
|
|
65
65
|
this._cacheManager = cacheManager;
|
|
66
66
|
this._buildManifest = buildManifest;
|
|
67
|
+
this._virtualMap = virtualMap;
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
69
70
|
* @return The `CacheManager` for this runtime instance.
|
|
@@ -101,6 +102,18 @@ class Runtime {
|
|
|
101
102
|
set buildManifest(manifest) {
|
|
102
103
|
this._buildManifest = manifest;
|
|
103
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* The virtual map for virtual source resolution.
|
|
107
|
+
* When set, compiled queries automatically resolve virtual sources
|
|
108
|
+
* against this map. Can be overridden per-query via
|
|
109
|
+
* CompileQueryOptions.virtualMap.
|
|
110
|
+
*/
|
|
111
|
+
get virtualMap() {
|
|
112
|
+
return this._virtualMap;
|
|
113
|
+
}
|
|
114
|
+
set virtualMap(map) {
|
|
115
|
+
this._virtualMap = map;
|
|
116
|
+
}
|
|
104
117
|
/**
|
|
105
118
|
* Load a Malloy model by URL or contents.
|
|
106
119
|
*
|
|
@@ -223,23 +236,25 @@ exports.Runtime = Runtime;
|
|
|
223
236
|
// ConnectionRuntime and SingleConnectionRuntime
|
|
224
237
|
// =============================================================================
|
|
225
238
|
class ConnectionRuntime extends Runtime {
|
|
226
|
-
constructor({ urlReader, connections, buildManifest, }) {
|
|
239
|
+
constructor({ urlReader, connections, buildManifest, virtualMap, }) {
|
|
227
240
|
super({
|
|
228
241
|
connections: readers_1.FixedConnectionMap.fromArray(connections),
|
|
229
242
|
urlReader,
|
|
230
243
|
buildManifest,
|
|
244
|
+
virtualMap,
|
|
231
245
|
});
|
|
232
246
|
this.rawConnections = connections;
|
|
233
247
|
}
|
|
234
248
|
}
|
|
235
249
|
exports.ConnectionRuntime = ConnectionRuntime;
|
|
236
250
|
class SingleConnectionRuntime extends Runtime {
|
|
237
|
-
constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, }) {
|
|
251
|
+
constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, virtualMap, }) {
|
|
238
252
|
super({
|
|
239
253
|
urlReader,
|
|
240
254
|
eventStream,
|
|
241
255
|
cacheManager,
|
|
242
256
|
buildManifest,
|
|
257
|
+
virtualMap,
|
|
243
258
|
connection,
|
|
244
259
|
});
|
|
245
260
|
this.connection = connection;
|
|
@@ -569,7 +584,7 @@ class QueryMaterializer extends FluentState {
|
|
|
569
584
|
*/
|
|
570
585
|
loadPreparedResult(options) {
|
|
571
586
|
return this.makePreparedResultMaterializer(async () => {
|
|
572
|
-
var _a;
|
|
587
|
+
var _a, _b;
|
|
573
588
|
const preparedQuery = await this.materialize();
|
|
574
589
|
const mergedOptions = {
|
|
575
590
|
eventStream: this.eventStream,
|
|
@@ -610,11 +625,14 @@ class QueryMaterializer extends FluentState {
|
|
|
610
625
|
connectionDigests[connName] = conn.getDigest();
|
|
611
626
|
}
|
|
612
627
|
}
|
|
628
|
+
// Use virtualMap from options if provided, otherwise fall back to Runtime's.
|
|
629
|
+
const virtualMap = (_b = mergedOptions.virtualMap) !== null && _b !== void 0 ? _b : this.runtime.virtualMap;
|
|
613
630
|
// Build PrepareResultOptions from CompileQueryOptions + connectionDigests
|
|
614
631
|
const prepareResultOptions = {
|
|
615
632
|
defaultRowLimit: mergedOptions.defaultRowLimit,
|
|
616
633
|
buildManifest,
|
|
617
634
|
connectionDigests,
|
|
635
|
+
virtualMap,
|
|
618
636
|
};
|
|
619
637
|
return preparedQuery.getPreparedResult({
|
|
620
638
|
...mergedOptions,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EventStream } from '../../runtime_types';
|
|
2
|
-
import type { BuildManifest } from '../../model';
|
|
2
|
+
import type { BuildManifest, VirtualMap } from '../../model';
|
|
3
3
|
/**
|
|
4
4
|
* An empty BuildManifest with no entries and strict mode off.
|
|
5
5
|
* Use this to explicitly suppress manifest substitution in a query:
|
|
@@ -33,6 +33,8 @@ export interface CompileQueryOptions {
|
|
|
33
33
|
buildManifest?: BuildManifest;
|
|
34
34
|
/** Map from connectionName to connectionDigest (from Connection.getDigest()) */
|
|
35
35
|
connectionDigests?: Record<string, string>;
|
|
36
|
+
/** Map from connectionName → virtualName → tablePath for virtual source resolution */
|
|
37
|
+
virtualMap?: VirtualMap;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* A node in the build graph (recursive DAG structure).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
|
|
2
2
|
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
|
|
3
|
-
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, } from './model';
|
|
3
|
+
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, VirtualMap, } from './model';
|
|
4
4
|
export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
5
5
|
export { malloyToQuery, MalloyTranslator, } from './lang';
|
|
6
6
|
export type { LogMessage, TranslateResponse } from './lang';
|
package/dist/lang/ast/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './query-properties/nest';
|
|
2
2
|
export * from './statements/define-source';
|
|
3
|
+
export * from './statements/define-user-type';
|
|
3
4
|
export * from './statements/define-query';
|
|
4
5
|
export * from './source-elements/source';
|
|
5
6
|
export * from './source-elements/refined-source';
|
|
@@ -9,6 +10,7 @@ export * from './source-query-elements/sq-refine';
|
|
|
9
10
|
export * from './source-query-elements/sq-source';
|
|
10
11
|
export * from './source-query-elements/sq-reference';
|
|
11
12
|
export * from './source-query-elements/sq-extend';
|
|
13
|
+
export * from './source-query-elements/sq-typed-source';
|
|
12
14
|
export * from './source-query-elements/sq-compose';
|
|
13
15
|
export * from './source-query-elements/include-item';
|
|
14
16
|
export * from './source-properties/field-list-edit';
|
|
@@ -16,6 +18,7 @@ export * from './source-properties/primary-key';
|
|
|
16
18
|
export * from './source-properties/renames';
|
|
17
19
|
export * from './source-properties/views';
|
|
18
20
|
export * from './source-properties/timezone-statement';
|
|
21
|
+
export * from './source-properties/user-type-shape';
|
|
19
22
|
export * from './expressions/apply';
|
|
20
23
|
export * from './expressions/binary-numeric';
|
|
21
24
|
export * from './expressions/boolean';
|
|
@@ -100,6 +103,8 @@ export * from './source-elements/named-source';
|
|
|
100
103
|
export * from './source-elements/query-source';
|
|
101
104
|
export * from './source-elements/sql-source';
|
|
102
105
|
export * from './source-elements/table-source';
|
|
106
|
+
export * from './source-elements/typed-source';
|
|
107
|
+
export * from './source-elements/virtual-source';
|
|
103
108
|
export * from './sql-elements/sql-string';
|
|
104
109
|
export * from './types/annotation-elements';
|
|
105
110
|
export * from './types/binary_operators';
|
package/dist/lang/ast/index.js
CHANGED
|
@@ -38,6 +38,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
__exportStar(require("./query-properties/nest"), exports);
|
|
40
40
|
__exportStar(require("./statements/define-source"), exports);
|
|
41
|
+
__exportStar(require("./statements/define-user-type"), exports);
|
|
41
42
|
__exportStar(require("./statements/define-query"), exports);
|
|
42
43
|
__exportStar(require("./source-elements/source"), exports);
|
|
43
44
|
__exportStar(require("./source-elements/refined-source"), exports);
|
|
@@ -47,6 +48,7 @@ __exportStar(require("./source-query-elements/sq-refine"), exports);
|
|
|
47
48
|
__exportStar(require("./source-query-elements/sq-source"), exports);
|
|
48
49
|
__exportStar(require("./source-query-elements/sq-reference"), exports);
|
|
49
50
|
__exportStar(require("./source-query-elements/sq-extend"), exports);
|
|
51
|
+
__exportStar(require("./source-query-elements/sq-typed-source"), exports);
|
|
50
52
|
__exportStar(require("./source-query-elements/sq-compose"), exports);
|
|
51
53
|
__exportStar(require("./source-query-elements/include-item"), exports);
|
|
52
54
|
__exportStar(require("./source-properties/field-list-edit"), exports);
|
|
@@ -54,6 +56,7 @@ __exportStar(require("./source-properties/primary-key"), exports);
|
|
|
54
56
|
__exportStar(require("./source-properties/renames"), exports);
|
|
55
57
|
__exportStar(require("./source-properties/views"), exports);
|
|
56
58
|
__exportStar(require("./source-properties/timezone-statement"), exports);
|
|
59
|
+
__exportStar(require("./source-properties/user-type-shape"), exports);
|
|
57
60
|
__exportStar(require("./expressions/apply"), exports);
|
|
58
61
|
__exportStar(require("./expressions/binary-numeric"), exports);
|
|
59
62
|
__exportStar(require("./expressions/boolean"), exports);
|
|
@@ -138,6 +141,8 @@ __exportStar(require("./source-elements/named-source"), exports);
|
|
|
138
141
|
__exportStar(require("./source-elements/query-source"), exports);
|
|
139
142
|
__exportStar(require("./source-elements/sql-source"), exports);
|
|
140
143
|
__exportStar(require("./source-elements/table-source"), exports);
|
|
144
|
+
__exportStar(require("./source-elements/typed-source"), exports);
|
|
145
|
+
__exportStar(require("./source-elements/virtual-source"), exports);
|
|
141
146
|
__exportStar(require("./sql-elements/sql-string"), exports);
|
|
142
147
|
__exportStar(require("./types/annotation-elements"), exports);
|
|
143
148
|
__exportStar(require("./types/binary_operators"), exports);
|
|
@@ -99,6 +99,10 @@ class NamedSource extends source_1.Source {
|
|
|
99
99
|
this.logError('invalid-source-from-connection', `Cannot construct a source from a connection '${this.refName}'`);
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
+
else if (entry.type === 'userType') {
|
|
103
|
+
this.logError('invalid-source-from-user-type', `Cannot construct a source from a user type '${this.refName}'`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
102
106
|
else {
|
|
103
107
|
(_a = this.document()) === null || _a === void 0 ? void 0 : _a.checkExperimentalDialect(this, entry.dialect);
|
|
104
108
|
if ((0, malloy_types_1.isSourceDef)(entry)) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { NonDefaultAccessModifierLabel, SourceDef } from '../../../model/malloy_types';
|
|
2
|
+
import { Source } from './source';
|
|
3
|
+
import type { ParameterSpace } from '../field-space/parameter-space';
|
|
4
|
+
import type { ModelEntryReference } from '../types/malloy-element';
|
|
5
|
+
export declare const USER_TYPE_HIDDEN_ACCESS: NonDefaultAccessModifierLabel;
|
|
6
|
+
/**
|
|
7
|
+
* A Source wrapped with user type constraints via the `::` operator.
|
|
8
|
+
* Resolves and merges user types (validating no conflicts), then:
|
|
9
|
+
* - virtual sources: user-type fields not in the source are added
|
|
10
|
+
* - all other sources: user-type fields not in the source are an error
|
|
11
|
+
* - in both cases: source fields not in any user type are marked
|
|
12
|
+
* with USER_TYPE_HIDDEN_ACCESS
|
|
13
|
+
*
|
|
14
|
+
* e.g. `source::MyType` or `source::(A, B)`
|
|
15
|
+
*/
|
|
16
|
+
export declare class TypedSource extends Source {
|
|
17
|
+
readonly innerSource: Source;
|
|
18
|
+
readonly userTypes: ModelEntryReference[];
|
|
19
|
+
elementType: string;
|
|
20
|
+
constructor(innerSource: Source, userTypes: ModelEntryReference[]);
|
|
21
|
+
getSourceDef(parameterSpace: ParameterSpace | undefined): SourceDef;
|
|
22
|
+
private nextShape;
|
|
23
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.TypedSource = exports.USER_TYPE_HIDDEN_ACCESS = void 0;
|
|
8
|
+
const malloy_types_1 = require("../../../model/malloy_types");
|
|
9
|
+
const source_1 = require("./source");
|
|
10
|
+
exports.USER_TYPE_HIDDEN_ACCESS = 'internal';
|
|
11
|
+
/**
|
|
12
|
+
* With each field, keep the shape reference it came from, for error reporting
|
|
13
|
+
*/
|
|
14
|
+
class Shape extends Map {
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A Source wrapped with user type constraints via the `::` operator.
|
|
18
|
+
* Resolves and merges user types (validating no conflicts), then:
|
|
19
|
+
* - virtual sources: user-type fields not in the source are added
|
|
20
|
+
* - all other sources: user-type fields not in the source are an error
|
|
21
|
+
* - in both cases: source fields not in any user type are marked
|
|
22
|
+
* with USER_TYPE_HIDDEN_ACCESS
|
|
23
|
+
*
|
|
24
|
+
* e.g. `source::MyType` or `source::(A, B)`
|
|
25
|
+
*/
|
|
26
|
+
class TypedSource extends source_1.Source {
|
|
27
|
+
constructor(innerSource, userTypes) {
|
|
28
|
+
super({ innerSource });
|
|
29
|
+
this.innerSource = innerSource;
|
|
30
|
+
this.userTypes = userTypes;
|
|
31
|
+
this.elementType = 'typedSource';
|
|
32
|
+
this.has({ userTypes });
|
|
33
|
+
}
|
|
34
|
+
getSourceDef(parameterSpace) {
|
|
35
|
+
const sourceDef = this.innerSource.getSourceDef(parameterSpace);
|
|
36
|
+
// Merge user types, while validating no field conflicts
|
|
37
|
+
const [outputShape, ...remainingShapes] = this.nextShape();
|
|
38
|
+
if (outputShape === undefined) {
|
|
39
|
+
return sourceDef;
|
|
40
|
+
}
|
|
41
|
+
for (const mergeShape of remainingShapes) {
|
|
42
|
+
for (const [name, { field, fromShape }] of mergeShape) {
|
|
43
|
+
const existing = outputShape.get(name);
|
|
44
|
+
if (existing && !malloy_types_1.TD.eq(field, existing.field)) {
|
|
45
|
+
fromShape.logError('user-type-field-conflict', `Field '${name}' has conflicting types in user types '${existing.fromShape.name}' and '${fromShape.name}'`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
outputShape.set(name, { field, fromShape });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const isVirtual = sourceDef.type === 'virtual';
|
|
53
|
+
const sourceFields = new Map(sourceDef.fields.map(f => { var _a; return [(_a = f.as) !== null && _a !== void 0 ? _a : f.name, f]; }));
|
|
54
|
+
const fieldsToAdd = [];
|
|
55
|
+
// Validate/Enforce that this source matches the shape
|
|
56
|
+
for (const [name, { field, fromShape }] of outputShape) {
|
|
57
|
+
const sourceField = sourceFields.get(name);
|
|
58
|
+
if (sourceField === undefined) {
|
|
59
|
+
if (isVirtual) {
|
|
60
|
+
fieldsToAdd.push(field);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
fromShape.logError('user-type-field-missing', `Source is missing field '${field.name}' required by user type '${fromShape.name}'`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (!isVirtual &&
|
|
67
|
+
(0, malloy_types_1.fieldIsIntrinsic)(sourceField) &&
|
|
68
|
+
!malloy_types_1.TD.eq(field, sourceField)) {
|
|
69
|
+
fromShape.logError('user-type-type-mismatch', `Type mismatch for '${name}': user type '${fromShape.name}' declares ${field.type} but source has ${sourceField.type}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Intrinsic fields not in any shape: mark as hidden.
|
|
73
|
+
// Matching fields inherit annotations from the shape.
|
|
74
|
+
const resultFields = sourceDef.fields.map(f => {
|
|
75
|
+
var _a;
|
|
76
|
+
const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
|
|
77
|
+
const shapeEntry = outputShape.get(name);
|
|
78
|
+
if (!shapeEntry || !(0, malloy_types_1.fieldIsIntrinsic)(f)) {
|
|
79
|
+
return (0, malloy_types_1.fieldIsIntrinsic)(f) && !shapeEntry
|
|
80
|
+
? { ...f, accessModifier: exports.USER_TYPE_HIDDEN_ACCESS }
|
|
81
|
+
: f;
|
|
82
|
+
}
|
|
83
|
+
const shapeAnnotation = shapeEntry.field.annotation;
|
|
84
|
+
if (!shapeAnnotation) {
|
|
85
|
+
return f;
|
|
86
|
+
}
|
|
87
|
+
return { ...f, annotation: mergeAnnotation(f.annotation, shapeAnnotation) };
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
...sourceDef,
|
|
91
|
+
fields: [...resultFields, ...fieldsToAdd],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
*nextShape() {
|
|
95
|
+
for (const ref of this.userTypes) {
|
|
96
|
+
const next = new Shape();
|
|
97
|
+
const entry = this.modelEntry(ref);
|
|
98
|
+
if (entry === undefined) {
|
|
99
|
+
ref.logError('user-type-not-found', `User type '${ref.name}' is not defined`);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (!(0, malloy_types_1.isUserTypeDef)(entry.entry)) {
|
|
103
|
+
ref.logError('not-a-user-type', `'${ref.name}' is not a user type`);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
for (const sf of entry.entry.fields) {
|
|
107
|
+
const field = (0, malloy_types_1.mkFieldDef)(sf.typeDef, sf.name);
|
|
108
|
+
if (sf.annotation) {
|
|
109
|
+
field.annotation = sf.annotation;
|
|
110
|
+
}
|
|
111
|
+
next.set(sf.name, { field, fromShape: ref });
|
|
112
|
+
}
|
|
113
|
+
yield next;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.TypedSource = TypedSource;
|
|
118
|
+
/**
|
|
119
|
+
* Insert shapeAnnotation behind fieldAnnotation in the inherits chain.
|
|
120
|
+
* Chain: field → shape → (whatever field previously inherited from)
|
|
121
|
+
*/
|
|
122
|
+
function mergeAnnotation(fieldAnnotation, shapeAnnotation) {
|
|
123
|
+
if (!fieldAnnotation) {
|
|
124
|
+
return shapeAnnotation;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
...fieldAnnotation,
|
|
128
|
+
inherits: fieldAnnotation.inherits
|
|
129
|
+
? { ...shapeAnnotation, inherits: fieldAnnotation.inherits }
|
|
130
|
+
: shapeAnnotation,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=typed-source.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SourceDef } from '../../../model/malloy_types';
|
|
2
|
+
import { Source } from './source';
|
|
3
|
+
import type { ModelEntryReference } from '../types/malloy-element';
|
|
4
|
+
export declare class VirtualTableSource extends Source {
|
|
5
|
+
readonly connectionName: ModelEntryReference;
|
|
6
|
+
readonly virtualName: string;
|
|
7
|
+
elementType: string;
|
|
8
|
+
constructor(connectionName: ModelEntryReference, virtualName: string);
|
|
9
|
+
getSourceDef(): SourceDef;
|
|
10
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.VirtualTableSource = void 0;
|
|
8
|
+
const source_1 = require("./source");
|
|
9
|
+
const error_factory_1 = require("../error-factory");
|
|
10
|
+
class VirtualTableSource extends source_1.Source {
|
|
11
|
+
constructor(connectionName, virtualName) {
|
|
12
|
+
super();
|
|
13
|
+
this.connectionName = connectionName;
|
|
14
|
+
this.virtualName = virtualName;
|
|
15
|
+
this.elementType = 'virtualTableSource';
|
|
16
|
+
this.has({ connectionName });
|
|
17
|
+
}
|
|
18
|
+
getSourceDef() {
|
|
19
|
+
var _a, _b, _c;
|
|
20
|
+
const connection = this.modelEntry(this.connectionName);
|
|
21
|
+
const name = this.connectionName.refString;
|
|
22
|
+
if (connection === undefined) {
|
|
23
|
+
(_a = this.namespace()) === null || _a === void 0 ? void 0 : _a.setEntry(name, { entry: { type: 'connection', name }, exported: true }, true);
|
|
24
|
+
}
|
|
25
|
+
else if (connection.entry.type !== 'connection') {
|
|
26
|
+
this.connectionName.logError('invalid-connection-for-table-source', `${this.connectionName.refString} is not a connection`);
|
|
27
|
+
return error_factory_1.ErrorFactory.structDef;
|
|
28
|
+
}
|
|
29
|
+
const dialect = (_b = this.translator()) === null || _b === void 0 ? void 0 : _b.root.connectionDialectZone.get(name);
|
|
30
|
+
if (dialect === undefined) {
|
|
31
|
+
this.logError('virtual-source-unknown-dialect', `Cannot determine dialect for connection '${name}'`);
|
|
32
|
+
return error_factory_1.ErrorFactory.structDef;
|
|
33
|
+
}
|
|
34
|
+
const sourceDef = {
|
|
35
|
+
type: 'virtual',
|
|
36
|
+
name: this.virtualName,
|
|
37
|
+
dialect,
|
|
38
|
+
connection: name,
|
|
39
|
+
fields: [],
|
|
40
|
+
location: this.location,
|
|
41
|
+
};
|
|
42
|
+
(_c = this.document()) === null || _c === void 0 ? void 0 : _c.rememberToAddModelAnnotations(sourceDef);
|
|
43
|
+
return sourceDef;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.VirtualTableSource = VirtualTableSource;
|
|
47
|
+
//# sourceMappingURL=virtual-source.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Annotation, AtomicTypeDef, UserTypeFieldDef } from '../../../model/malloy_types';
|
|
2
|
+
import { ListOf, MalloyElement } from '../types/malloy-element';
|
|
3
|
+
import type { Noteable } from '../types/noteable';
|
|
4
|
+
import { extendNoteMethod } from '../types/noteable';
|
|
5
|
+
export declare abstract class UserTypeMember extends MalloyElement implements Noteable {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly isNoteableObj = true;
|
|
8
|
+
extendNote: typeof extendNoteMethod;
|
|
9
|
+
note?: Annotation;
|
|
10
|
+
constructor(name: string);
|
|
11
|
+
abstract userTypeFieldDef(): UserTypeFieldDef;
|
|
12
|
+
}
|
|
13
|
+
export declare class UserTypeMemberDef extends UserTypeMember {
|
|
14
|
+
readonly typeDef: AtomicTypeDef;
|
|
15
|
+
elementType: string;
|
|
16
|
+
constructor(name: string, typeDef: AtomicTypeDef);
|
|
17
|
+
userTypeFieldDef(): UserTypeFieldDef;
|
|
18
|
+
}
|
|
19
|
+
export declare class UserTypeMemberIndirect extends UserTypeMember {
|
|
20
|
+
readonly shapeName: string;
|
|
21
|
+
readonly arrayDepth: number;
|
|
22
|
+
elementType: string;
|
|
23
|
+
constructor(name: string, shapeName: string, arrayDepth?: number);
|
|
24
|
+
userTypeFieldDef(): UserTypeFieldDef;
|
|
25
|
+
}
|
|
26
|
+
export declare class UserTypeShape extends ListOf<UserTypeMember> {
|
|
27
|
+
elementType: string;
|
|
28
|
+
userTypeFieldDefs(): UserTypeFieldDef[];
|
|
29
|
+
}
|