@malloydata/malloy 0.0.299 → 0.0.300
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/asynchronous.d.ts +1 -1
- package/dist/api/core.js +14 -10
- package/dist/api/sessioned.js +5 -1
- package/dist/dialect/functions/util.js +8 -2
- package/dist/lang/ast/error-factory.js +17 -3
- package/dist/lang/ast/expressions/constant-expression.d.ts +1 -0
- package/dist/lang/ast/expressions/constant-expression.js +3 -0
- package/dist/lang/ast/expressions/expr-props.d.ts +12 -0
- package/dist/lang/ast/field-space/dynamic-space.js +1 -1
- package/dist/lang/ast/field-space/index-field-space.d.ts +2 -1
- package/dist/lang/ast/field-space/index-field-space.js +20 -2
- package/dist/lang/ast/field-space/join-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/join-space-field.js +2 -2
- package/dist/lang/ast/field-space/parameter-space.d.ts +1 -0
- package/dist/lang/ast/field-space/parameter-space.js +3 -0
- package/dist/lang/ast/field-space/passthrough-space.d.ts +1 -0
- package/dist/lang/ast/field-space/passthrough-space.js +3 -0
- package/dist/lang/ast/field-space/query-input-space.d.ts +1 -0
- package/dist/lang/ast/field-space/query-input-space.js +3 -0
- package/dist/lang/ast/field-space/query-spaces.d.ts +13 -1
- package/dist/lang/ast/field-space/query-spaces.js +128 -29
- package/dist/lang/ast/field-space/refine-from-space-field.d.ts +9 -0
- package/dist/lang/ast/field-space/refine-from-space-field.js +24 -0
- package/dist/lang/ast/field-space/static-space.d.ts +6 -3
- package/dist/lang/ast/field-space/static-space.js +13 -10
- package/dist/lang/ast/field-space/view-field.d.ts +2 -108
- package/dist/lang/ast/field-space/view-field.js +1 -40
- package/dist/lang/ast/query-builders/reduce-builder.js +1 -0
- package/dist/lang/ast/query-elements/query-raw.js +1 -1
- package/dist/lang/ast/query-elements/query-reference.js +1 -2
- package/dist/lang/ast/query-elements/query-refine.js +5 -5
- package/dist/lang/ast/query-items/field-references.d.ts +4 -0
- package/dist/lang/ast/query-items/field-references.js +12 -1
- package/dist/lang/ast/query-properties/qop-desc.js +1 -7
- package/dist/lang/ast/source-elements/query-source.js +1 -0
- package/dist/lang/ast/source-elements/refined-source.js +2 -2
- package/dist/lang/ast/source-properties/join.js +1 -1
- package/dist/lang/ast/typedesc-utils.d.ts +0 -1
- package/dist/lang/ast/typedesc-utils.js +1 -2
- package/dist/lang/ast/types/field-space.d.ts +2 -0
- package/dist/lang/ast/types/malloy-element.js +2 -2
- package/dist/lang/ast/types/op-desc.d.ts +1 -1
- package/dist/lang/ast/types/space-field.d.ts +3 -1
- package/dist/lang/ast/types/space-field.js +22 -0
- package/dist/lang/ast/view-elements/qop-desc-view.js +8 -4
- package/dist/lang/ast/view-elements/reference-view.js +9 -7
- package/dist/lang/ast/view-elements/view-refine.js +1 -2
- package/dist/lang/test/test-translator.js +11 -0
- package/dist/malloy.js +8 -6
- package/dist/model/malloy_query.js +19 -4
- package/dist/model/malloy_types.d.ts +13 -4
- package/dist/model/malloy_types.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/dist/lang/ast/struct-utils.d.ts +0 -5
- package/dist/lang/ast/struct-utils.js +0 -69
|
@@ -10,4 +10,4 @@ export interface CompilerNeedFetch<T extends InfoConnection> {
|
|
|
10
10
|
export declare function compileModel(request: Malloy.CompileModelRequest, fetchers: CompilerNeedFetch<InfoConnection>): Promise<Malloy.CompileModelResponse>;
|
|
11
11
|
export declare function compileSource(request: Malloy.CompileSourceRequest, fetchers: CompilerNeedFetch<InfoConnection>): Promise<Malloy.CompileSourceResponse>;
|
|
12
12
|
export declare function compileQuery(request: Malloy.CompileQueryRequest, fetchers: CompilerNeedFetch<InfoConnection>): Promise<Malloy.CompileQueryResponse>;
|
|
13
|
-
export declare function runQuery(request: Malloy.
|
|
13
|
+
export declare function runQuery(request: Malloy.RunQueryRequest, fetchers: CompilerNeedFetch<Connection>): Promise<Malloy.RunQueryResponse>;
|
package/dist/api/core.js
CHANGED
|
@@ -258,14 +258,15 @@ function updateCompileModelState(state, needs) {
|
|
|
258
258
|
const update = compilerNeedsToUpdate(needs);
|
|
259
259
|
performUpdate(state, update);
|
|
260
260
|
}
|
|
261
|
-
function _newCompileModelState(modelURL, compilerNeeds, extendURL, excludeReferences = false) {
|
|
261
|
+
function _newCompileModelState(modelURL, compilerNeeds, parseUpdate, extendURL, excludeReferences = false) {
|
|
262
262
|
var _a, _b, _c, _d;
|
|
263
|
-
|
|
263
|
+
parseUpdate !== null && parseUpdate !== void 0 ? parseUpdate : (parseUpdate = compilerNeedsToUpdate(compilerNeeds));
|
|
264
|
+
const translator = new lang_1.MalloyTranslator(modelURL, null, parseUpdate);
|
|
264
265
|
const hasSource = ((_b = (_a = compilerNeeds === null || compilerNeeds === void 0 ? void 0 : compilerNeeds.files) === null || _a === void 0 ? void 0 : _a.some(f => f.url === modelURL)) !== null && _b !== void 0 ? _b : false) ||
|
|
265
266
|
((_d = (_c = compilerNeeds === null || compilerNeeds === void 0 ? void 0 : compilerNeeds.translations) === null || _c === void 0 ? void 0 : _c.some(t => t.url === modelURL)) !== null && _d !== void 0 ? _d : false);
|
|
266
267
|
if (extendURL) {
|
|
267
268
|
return {
|
|
268
|
-
extending: _newCompileModelState(extendURL, compilerNeeds, undefined, excludeReferences),
|
|
269
|
+
extending: _newCompileModelState(extendURL, compilerNeeds, parseUpdate, undefined, excludeReferences),
|
|
269
270
|
translator,
|
|
270
271
|
done: false,
|
|
271
272
|
hasSource,
|
|
@@ -282,10 +283,10 @@ function _newCompileModelState(modelURL, compilerNeeds, extendURL, excludeRefere
|
|
|
282
283
|
}
|
|
283
284
|
}
|
|
284
285
|
function newCompileModelState(request) {
|
|
285
|
-
return _newCompileModelState(request.model_url, request.compiler_needs, request.extend_model_url, request.exclude_references);
|
|
286
|
+
return _newCompileModelState(request.model_url, request.compiler_needs, undefined, request.extend_model_url, request.exclude_references);
|
|
286
287
|
}
|
|
287
288
|
function newCompileSourceState(request) {
|
|
288
|
-
return _newCompileModelState(request.model_url, request.compiler_needs, request.extend_model_url, request.exclude_references);
|
|
289
|
+
return _newCompileModelState(request.model_url, request.compiler_needs, undefined, request.extend_model_url, request.exclude_references);
|
|
289
290
|
}
|
|
290
291
|
// function hasNeeds(needs: Malloy.CompilerNeeds | undefined): boolean {
|
|
291
292
|
// if (needs === undefined) return false;
|
|
@@ -427,10 +428,13 @@ function hasErrors(log) {
|
|
|
427
428
|
return (_a = log === null || log === void 0 ? void 0 : log.some(m => m.severity === 'error')) !== null && _a !== void 0 ? _a : false;
|
|
428
429
|
}
|
|
429
430
|
function newCompileQueryState(request) {
|
|
430
|
-
var _a, _b;
|
|
431
|
-
const queryMalloy = Malloy.queryToMalloy(request.query);
|
|
431
|
+
var _a, _b, _c;
|
|
432
|
+
const queryMalloy = (_a = request.query_malloy) !== null && _a !== void 0 ? _a : (request.query ? Malloy.queryToMalloy(request.query) : undefined);
|
|
433
|
+
if (queryMalloy === undefined) {
|
|
434
|
+
throw new Error('Expected either query or query_malloy');
|
|
435
|
+
}
|
|
432
436
|
const needs = {
|
|
433
|
-
...((
|
|
437
|
+
...((_b = request.compiler_needs) !== null && _b !== void 0 ? _b : {}),
|
|
434
438
|
};
|
|
435
439
|
const queryURL = 'internal://query.malloy';
|
|
436
440
|
needs.files = [
|
|
@@ -438,10 +442,10 @@ function newCompileQueryState(request) {
|
|
|
438
442
|
url: queryURL,
|
|
439
443
|
contents: queryMalloy,
|
|
440
444
|
},
|
|
441
|
-
...((
|
|
445
|
+
...((_c = needs.files) !== null && _c !== void 0 ? _c : []),
|
|
442
446
|
];
|
|
443
447
|
return {
|
|
444
|
-
..._newCompileModelState(queryURL, needs, request.model_url, request.exclude_references),
|
|
448
|
+
..._newCompileModelState(queryURL, needs, undefined, request.model_url, request.exclude_references),
|
|
445
449
|
defaultRowLimit: request.default_row_limit,
|
|
446
450
|
};
|
|
447
451
|
}
|
package/dist/api/sessioned.js
CHANGED
|
@@ -242,7 +242,11 @@ class SessionManager {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
compileQuery(request, options) {
|
|
245
|
-
|
|
245
|
+
var _a;
|
|
246
|
+
const queryString = (_a = request.query_malloy) !== null && _a !== void 0 ? _a : (request.query ? Malloy.queryToMalloy(request.query) : undefined);
|
|
247
|
+
if (queryString === undefined) {
|
|
248
|
+
throw new Error('Expected query_malloy or query');
|
|
249
|
+
}
|
|
246
250
|
const sessionInfo = {
|
|
247
251
|
type: 'compile_query',
|
|
248
252
|
modelURL: request.model_url,
|
|
@@ -233,9 +233,12 @@ function expandReturnTypeBlueprint(blueprint) {
|
|
|
233
233
|
else if ('sql_native' in blueprint) {
|
|
234
234
|
return anyExprType({ type: 'sql native', rawType: blueprint.sql_native });
|
|
235
235
|
}
|
|
236
|
-
else {
|
|
236
|
+
else if ('calculation' in blueprint) {
|
|
237
237
|
return minAnalytic(expandTypeDescElementBlueprint(blueprint.calculation, false));
|
|
238
238
|
}
|
|
239
|
+
else {
|
|
240
|
+
throw new Error('Invalid function blueprint');
|
|
241
|
+
}
|
|
239
242
|
}
|
|
240
243
|
function isTypeDescBlueprint(blueprint) {
|
|
241
244
|
return (typeof blueprint === 'string' ||
|
|
@@ -291,9 +294,12 @@ function expandParamTypeBlueprint(blueprint) {
|
|
|
291
294
|
else if ('sql_native' in blueprint) {
|
|
292
295
|
return anyExprType({ type: 'sql native', rawType: blueprint.sql_native });
|
|
293
296
|
}
|
|
294
|
-
else {
|
|
297
|
+
else if ('calculation' in blueprint) {
|
|
295
298
|
return maxAnalytic(expandTypeDescElementBlueprint(blueprint.calculation));
|
|
296
299
|
}
|
|
300
|
+
else {
|
|
301
|
+
throw new Error('Invalid function blueprint');
|
|
302
|
+
}
|
|
297
303
|
}
|
|
298
304
|
function expandParamTypeBlueprints(blueprints) {
|
|
299
305
|
return blueprints.map(blueprint => expandParamTypeBlueprint(blueprint));
|
|
@@ -61,13 +61,27 @@ class ErrorFactory {
|
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
static get reduceSegment() {
|
|
64
|
-
return {
|
|
64
|
+
return {
|
|
65
|
+
type: 'reduce',
|
|
66
|
+
queryFields: [],
|
|
67
|
+
outputStruct: ErrorFactory.structDef,
|
|
68
|
+
isRepeated: false,
|
|
69
|
+
};
|
|
65
70
|
}
|
|
66
71
|
static get projectSegment() {
|
|
67
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
type: 'project',
|
|
74
|
+
queryFields: [],
|
|
75
|
+
outputStruct: ErrorFactory.structDef,
|
|
76
|
+
isRepeated: true,
|
|
77
|
+
};
|
|
68
78
|
}
|
|
69
79
|
static get indexSegment() {
|
|
70
|
-
return {
|
|
80
|
+
return {
|
|
81
|
+
type: 'index',
|
|
82
|
+
indexFields: [],
|
|
83
|
+
outputStruct: ErrorFactory.structDef,
|
|
84
|
+
};
|
|
71
85
|
}
|
|
72
86
|
}
|
|
73
87
|
exports.ErrorFactory = ErrorFactory;
|
|
@@ -14,6 +14,7 @@ export declare class ConstantFieldSpace implements FieldSpace {
|
|
|
14
14
|
entry(): undefined;
|
|
15
15
|
dialectName(): string;
|
|
16
16
|
dialectObj(): undefined;
|
|
17
|
+
connectionName(): string;
|
|
17
18
|
isQueryFieldSpace(): this is QueryFieldSpace;
|
|
18
19
|
accessProtectionLevel(): AccessModifierLabel;
|
|
19
20
|
}
|
|
@@ -153,6 +153,18 @@ export declare class ExprProps extends ExpressionDef {
|
|
|
153
153
|
morphic?: {
|
|
154
154
|
[x: string]: import("../../../model/malloy_types").Expr;
|
|
155
155
|
};
|
|
156
|
+
} | {
|
|
157
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
158
|
+
type: "turtle";
|
|
159
|
+
pipeline: import("../../../model/malloy_types").PipeSegment[];
|
|
160
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
161
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
162
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
163
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[];
|
|
164
|
+
value: import("../../../model/malloy_types").Expr;
|
|
165
|
+
morphic?: {
|
|
166
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
167
|
+
};
|
|
156
168
|
} | {
|
|
157
169
|
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
158
170
|
type: "date";
|
|
@@ -68,7 +68,7 @@ const struct_space_field_base_1 = require("./struct-space-field-base");
|
|
|
68
68
|
const parameter_space_1 = require("./parameter-space");
|
|
69
69
|
class DynamicSpace extends static_space_1.StaticSpace {
|
|
70
70
|
constructor(extending) {
|
|
71
|
-
super(
|
|
71
|
+
super({ ...extending }, extending.dialect, extending.connection);
|
|
72
72
|
this.complete = false;
|
|
73
73
|
this.parameters = [];
|
|
74
74
|
this.newAccessModifiers = new Map();
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { IndexSegment, PipeSegment } from '../../../model/malloy_types';
|
|
1
|
+
import type { IndexSegment, PipeSegment, SourceDef } from '../../../model/malloy_types';
|
|
2
2
|
import { WildcardFieldReference } from '../query-items/field-references';
|
|
3
3
|
import type { MalloyElement } from '../types/malloy-element';
|
|
4
4
|
import { QueryOperationSpace } from './query-spaces';
|
|
5
5
|
export declare class IndexFieldSpace extends QueryOperationSpace {
|
|
6
6
|
readonly segmentType = "index";
|
|
7
7
|
pushFields(...defs: MalloyElement[]): void;
|
|
8
|
+
structDef(): SourceDef;
|
|
8
9
|
getPipeSegment(refineIndex?: PipeSegment): IndexSegment;
|
|
9
10
|
addRefineFromFields(_refineThis: never): void;
|
|
10
11
|
protected addWild(wild: WildcardFieldReference): void;
|
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.IndexFieldSpace = void 0;
|
|
26
26
|
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
27
27
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
28
|
+
const error_factory_1 = require("../error-factory");
|
|
28
29
|
const field_references_1 = require("../query-items/field-references");
|
|
29
30
|
const space_field_1 = require("../types/space-field");
|
|
30
31
|
const query_spaces_1 = require("./query-spaces");
|
|
@@ -48,11 +49,27 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
}
|
|
52
|
+
structDef() {
|
|
53
|
+
const connection = this.inputSpace().connectionName();
|
|
54
|
+
return {
|
|
55
|
+
type: 'query_result',
|
|
56
|
+
name: 'result',
|
|
57
|
+
dialect: this.dialectName(),
|
|
58
|
+
fields: [
|
|
59
|
+
{ type: 'string', name: 'fieldName' },
|
|
60
|
+
{ type: 'string', name: 'fieldPath' },
|
|
61
|
+
{ type: 'string', name: 'fieldValue' },
|
|
62
|
+
{ type: 'string', name: 'fieldType' },
|
|
63
|
+
{ type: 'number', name: 'weight', numberType: 'integer' },
|
|
64
|
+
],
|
|
65
|
+
connection,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
51
68
|
getPipeSegment(refineIndex) {
|
|
52
69
|
var _a;
|
|
53
70
|
if (refineIndex) {
|
|
54
71
|
this.logError('refinement-of-index-segment', 'index query operations cannot be refined');
|
|
55
|
-
return
|
|
72
|
+
return error_factory_1.ErrorFactory.indexSegment;
|
|
56
73
|
}
|
|
57
74
|
let fieldUsage = (0, composite_source_utils_1.emptyFieldUsage)();
|
|
58
75
|
const indexFields = [];
|
|
@@ -80,7 +97,8 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
|
|
|
80
97
|
}
|
|
81
98
|
}
|
|
82
99
|
this._fieldUsage = fieldUsage;
|
|
83
|
-
|
|
100
|
+
const outputStruct = this.structDef();
|
|
101
|
+
return { type: 'index', indexFields, outputStruct };
|
|
84
102
|
}
|
|
85
103
|
addRefineFromFields(_refineThis) { }
|
|
86
104
|
addWild(wild) {
|
|
@@ -4,5 +4,5 @@ import { StructSpaceField } from './static-space';
|
|
|
4
4
|
export declare class JoinSpaceField extends StructSpaceField {
|
|
5
5
|
readonly parameterSpace: ParameterSpace;
|
|
6
6
|
readonly join: Join;
|
|
7
|
-
constructor(parameterSpace: ParameterSpace, join: Join, forDialect: string);
|
|
7
|
+
constructor(parameterSpace: ParameterSpace, join: Join, forDialect: string, forConnection: string);
|
|
8
8
|
}
|
|
@@ -25,8 +25,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.JoinSpaceField = void 0;
|
|
26
26
|
const static_space_1 = require("./static-space");
|
|
27
27
|
class JoinSpaceField extends static_space_1.StructSpaceField {
|
|
28
|
-
constructor(parameterSpace, join, forDialect) {
|
|
29
|
-
super(join.getStructDef(parameterSpace), forDialect);
|
|
28
|
+
constructor(parameterSpace, join, forDialect, forConnection) {
|
|
29
|
+
super(join.getStructDef(parameterSpace), forDialect, forConnection);
|
|
30
30
|
this.parameterSpace = parameterSpace;
|
|
31
31
|
this.join = join;
|
|
32
32
|
}
|
|
@@ -14,6 +14,7 @@ export declare class ParameterSpace implements FieldSpace {
|
|
|
14
14
|
lookup(symbol: FieldName[]): LookupResult;
|
|
15
15
|
entries(): [string, SpaceEntry][];
|
|
16
16
|
dialectName(): string;
|
|
17
|
+
connectionName(): string;
|
|
17
18
|
dialectObj(): Dialect | undefined;
|
|
18
19
|
isQueryFieldSpace(): this is QueryFieldSpace;
|
|
19
20
|
accessProtectionLevel(): AccessModifierLabel;
|
|
@@ -18,4 +18,5 @@ export declare class PassthroughSpace implements FieldSpace {
|
|
|
18
18
|
outputSpace(): import("./query-spaces").QueryOperationSpace;
|
|
19
19
|
inputSpace(): import("../types/field-space").SourceFieldSpace;
|
|
20
20
|
accessProtectionLevel(): AccessModifierLabel;
|
|
21
|
+
connectionName(): string;
|
|
21
22
|
}
|
|
@@ -51,6 +51,9 @@ class PassthroughSpace {
|
|
|
51
51
|
accessProtectionLevel() {
|
|
52
52
|
return this.realFS.accessProtectionLevel();
|
|
53
53
|
}
|
|
54
|
+
connectionName() {
|
|
55
|
+
return this.realFS.connectionName();
|
|
56
|
+
}
|
|
54
57
|
}
|
|
55
58
|
exports.PassthroughSpace = PassthroughSpace;
|
|
56
59
|
//# sourceMappingURL=passthrough-space.js.map
|
|
@@ -59,6 +59,9 @@ class QueryInputSpace extends refined_space_1.RefinedSpace {
|
|
|
59
59
|
accessProtectionLevel() {
|
|
60
60
|
return this._accessProtectionLevel;
|
|
61
61
|
}
|
|
62
|
+
isQueryOutputSpace() {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
62
65
|
}
|
|
63
66
|
exports.QueryInputSpace = QueryInputSpace;
|
|
64
67
|
//# sourceMappingURL=query-input-space.js.map
|
|
@@ -9,6 +9,10 @@ import type { LookupResult } from '../types/lookup-result';
|
|
|
9
9
|
import { QueryInputSpace } from './query-input-space';
|
|
10
10
|
import type { SpaceEntry } from '../types/space-entry';
|
|
11
11
|
import type { LogMessageOptions, MessageCode, MessageParameterType } from '../../parse-log';
|
|
12
|
+
type TranslatedQueryField = {
|
|
13
|
+
queryFieldDef: model.QueryFieldDef;
|
|
14
|
+
typeDesc: model.TypeDesc;
|
|
15
|
+
};
|
|
12
16
|
/**
|
|
13
17
|
* The output space of a query operation. It is not named "QueryOutputSpace"
|
|
14
18
|
* because this is the namespace of the Query which is a layer of an output and
|
|
@@ -48,21 +52,29 @@ export declare abstract class QueryOperationSpace extends RefinedSpace implement
|
|
|
48
52
|
accessProtectionLevel(): model.AccessModifierLabel;
|
|
49
53
|
inputSpace(): QueryInputSpace;
|
|
50
54
|
outputSpace(): QueryOperationSpace;
|
|
55
|
+
isQueryOutputSpace(): boolean;
|
|
51
56
|
protected addWild(wild: WildcardFieldReference): void;
|
|
52
57
|
protected addValidatedCompositeFieldUserFromEntry(name: string, entry: SpaceEntry): void;
|
|
53
58
|
addFieldUserFromFilter(filter: model.FilterCondition): void;
|
|
54
59
|
newEntry(name: string, logTo: MalloyElement, entry: SpaceEntry): void;
|
|
60
|
+
isQueryFieldSpace(): this is QueryFieldSpace;
|
|
55
61
|
}
|
|
56
62
|
export declare abstract class QuerySpace extends QueryOperationSpace {
|
|
57
63
|
addRefineFromFields(refineThis: model.PipeSegment): void;
|
|
58
64
|
pushFields(...defs: MalloyElement[]): void;
|
|
59
65
|
canContain(_typeDescResult: model.TypeDesc | undefined): boolean;
|
|
60
66
|
protected queryFieldDefs(): model.QueryFieldDef[];
|
|
67
|
+
protected getOutputFieldDef(queryFieldDef: model.QueryFieldDef, typeDesc: model.TypeDesc): model.FieldDef;
|
|
68
|
+
protected getPrimaryKey(fields: TranslatedQueryField[]): string | undefined;
|
|
69
|
+
structDef(): model.SourceDef;
|
|
70
|
+
translatedQueryFields: TranslatedQueryField[] | undefined;
|
|
71
|
+
protected translateQueryFields(): TranslatedQueryField[];
|
|
61
72
|
getQuerySegment(rf: model.QuerySegment | undefined): model.QuerySegment;
|
|
73
|
+
protected isRepeated(): boolean;
|
|
62
74
|
getPipeSegment(refineFrom: model.QuerySegment | undefined): model.PipeSegment;
|
|
63
75
|
lookup(path: FieldName[]): LookupResult;
|
|
64
|
-
isQueryFieldSpace(): this is QueryFieldSpace;
|
|
65
76
|
}
|
|
66
77
|
export declare class ReduceFieldSpace extends QuerySpace {
|
|
67
78
|
readonly segmentType = "reduce";
|
|
68
79
|
}
|
|
80
|
+
export {};
|
|
@@ -62,10 +62,12 @@ const field_space_1 = require("../types/field-space");
|
|
|
62
62
|
const space_field_1 = require("../types/space-field");
|
|
63
63
|
const field_references_1 = require("../query-items/field-references");
|
|
64
64
|
const refined_space_1 = require("./refined-space");
|
|
65
|
-
const column_space_field_1 = require("./column-space-field");
|
|
66
65
|
const static_space_1 = require("./static-space");
|
|
67
66
|
const query_input_space_1 = require("./query-input-space");
|
|
68
67
|
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
68
|
+
const error_factory_1 = require("../error-factory");
|
|
69
|
+
const reference_field_1 = require("./reference-field");
|
|
70
|
+
const refine_from_space_field_1 = require("./refine-from-space-field");
|
|
69
71
|
/**
|
|
70
72
|
* The output space of a query operation. It is not named "QueryOutputSpace"
|
|
71
73
|
* because this is the namespace of the Query which is a layer of an output and
|
|
@@ -110,6 +112,9 @@ class QueryOperationSpace extends refined_space_1.RefinedSpace {
|
|
|
110
112
|
outputSpace() {
|
|
111
113
|
return this;
|
|
112
114
|
}
|
|
115
|
+
isQueryOutputSpace() {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
113
118
|
addWild(wild) {
|
|
114
119
|
var _a;
|
|
115
120
|
let current = this.exprSpace;
|
|
@@ -187,6 +192,9 @@ class QueryOperationSpace extends refined_space_1.RefinedSpace {
|
|
|
187
192
|
}
|
|
188
193
|
super.newEntry(name, logTo, entry);
|
|
189
194
|
}
|
|
195
|
+
isQueryFieldSpace() {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
190
198
|
}
|
|
191
199
|
exports.QueryOperationSpace = QueryOperationSpace;
|
|
192
200
|
// Project and Reduce or "QuerySegments" are built from a QuerySpace
|
|
@@ -204,17 +212,15 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
204
212
|
}
|
|
205
213
|
for (const field of refineThis.queryFields) {
|
|
206
214
|
if (field.type === 'fieldref') {
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
const fieldReference = new field_references_1.RefineFromFieldReference(field.path.map(f => new field_space_1.FieldName(f)));
|
|
216
|
+
this.astEl.has({ fieldReference });
|
|
217
|
+
const referenceField = new reference_field_1.ReferenceField(fieldReference, this.exprSpace);
|
|
218
|
+
const name = field.path[field.path.length - 1];
|
|
219
|
+
this.setEntry(name, referenceField);
|
|
220
|
+
this.addValidatedCompositeFieldUserFromEntry(name, referenceField);
|
|
213
221
|
}
|
|
214
|
-
else
|
|
215
|
-
|
|
216
|
-
// e.g. order_by: my_turtle.foo, or lag(my_turtle.foo)
|
|
217
|
-
const entry = new column_space_field_1.ColumnSpaceField(field);
|
|
222
|
+
else {
|
|
223
|
+
const entry = new refine_from_space_field_1.RefineFromSpaceField(field);
|
|
218
224
|
const name = (_a = field.as) !== null && _a !== void 0 ? _a : field.name;
|
|
219
225
|
this.setEntry(name, entry);
|
|
220
226
|
this.addValidatedCompositeFieldUserFromEntry(name, entry);
|
|
@@ -235,7 +241,91 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
235
241
|
return true;
|
|
236
242
|
}
|
|
237
243
|
queryFieldDefs() {
|
|
244
|
+
const fields = this.translateQueryFields();
|
|
245
|
+
return fields.map(f => f.queryFieldDef);
|
|
246
|
+
}
|
|
247
|
+
getOutputFieldDef(queryFieldDef, typeDesc) {
|
|
248
|
+
var _a, _b;
|
|
249
|
+
const name = queryFieldDef.type === 'fieldref'
|
|
250
|
+
? queryFieldDef.path[queryFieldDef.path.length - 1]
|
|
251
|
+
: (_a = queryFieldDef.as) !== null && _a !== void 0 ? _a : queryFieldDef.name;
|
|
252
|
+
if (typeDesc.type === 'turtle') {
|
|
253
|
+
const pipeline = typeDesc.pipeline;
|
|
254
|
+
const lastSegment = pipeline[pipeline.length - 1];
|
|
255
|
+
const outputStruct = (_b = lastSegment === null || lastSegment === void 0 ? void 0 : lastSegment.outputStruct) !== null && _b !== void 0 ? _b : error_factory_1.ErrorFactory.structDef;
|
|
256
|
+
const isRepeated = lastSegment
|
|
257
|
+
? model.isQuerySegment(lastSegment)
|
|
258
|
+
? lastSegment.isRepeated
|
|
259
|
+
: true
|
|
260
|
+
: true;
|
|
261
|
+
if (isRepeated) {
|
|
262
|
+
return {
|
|
263
|
+
...outputStruct,
|
|
264
|
+
elementTypeDef: { type: 'record_element' },
|
|
265
|
+
name: name,
|
|
266
|
+
type: 'array',
|
|
267
|
+
join: 'many',
|
|
268
|
+
as: undefined,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
return {
|
|
273
|
+
...outputStruct,
|
|
274
|
+
name: name,
|
|
275
|
+
type: 'record',
|
|
276
|
+
join: 'one',
|
|
277
|
+
as: undefined,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (model.TD.isAtomic(typeDesc)) {
|
|
282
|
+
const td = model.mkFieldDef(typeDesc, name);
|
|
283
|
+
return {
|
|
284
|
+
...td,
|
|
285
|
+
expressionType: 'scalar',
|
|
286
|
+
e: undefined,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
throw new Error('Invalid type for fieldref');
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Gets the primary key field for the output struct of this query;
|
|
294
|
+
// If there is exactly one scalar field, that is the primary key
|
|
295
|
+
getPrimaryKey(fields) {
|
|
296
|
+
var _a;
|
|
297
|
+
const dimensions = fields.filter(f => model.TD.isAtomic(f.typeDesc) &&
|
|
298
|
+
model.expressionIsScalar(f.typeDesc.expressionType));
|
|
299
|
+
if (dimensions.length !== 1)
|
|
300
|
+
return undefined;
|
|
301
|
+
const primaryKeyField = dimensions[0].queryFieldDef;
|
|
302
|
+
if (primaryKeyField.type === 'fieldref') {
|
|
303
|
+
return primaryKeyField.path[primaryKeyField.path.length - 1];
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
return (_a = primaryKeyField.as) !== null && _a !== void 0 ? _a : primaryKeyField.name;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// This returns the OUTPUT struct of this query space
|
|
310
|
+
structDef() {
|
|
311
|
+
const fields = this.translateQueryFields();
|
|
312
|
+
const sourceDef = {
|
|
313
|
+
type: 'query_result',
|
|
314
|
+
// TODO to match the compiler, does this need to be the name of the query?
|
|
315
|
+
name: 'query_result',
|
|
316
|
+
dialect: this.dialectName(),
|
|
317
|
+
// TODO need to get this in a less expensive way?
|
|
318
|
+
connection: this.inputSpace().connectionName(),
|
|
319
|
+
fields: fields.map(f => this.getOutputFieldDef(f.queryFieldDef, f.typeDesc)),
|
|
320
|
+
primaryKey: this.getPrimaryKey(fields),
|
|
321
|
+
};
|
|
322
|
+
return sourceDef;
|
|
323
|
+
}
|
|
324
|
+
translateQueryFields() {
|
|
238
325
|
var _a;
|
|
326
|
+
if (this.translatedQueryFields) {
|
|
327
|
+
return this.translatedQueryFields;
|
|
328
|
+
}
|
|
239
329
|
const fields = [];
|
|
240
330
|
let fieldUsage = (0, composite_source_utils_1.emptyFieldUsage)();
|
|
241
331
|
for (const user of this.compositeFieldUsers) {
|
|
@@ -249,12 +339,20 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
249
339
|
const { name, field } = user;
|
|
250
340
|
const wildPath = this.expandedWild[name];
|
|
251
341
|
if (wildPath) {
|
|
252
|
-
|
|
253
|
-
|
|
342
|
+
const typeDesc = wildPath.entry.typeDesc();
|
|
343
|
+
fields.push({
|
|
344
|
+
queryFieldDef: {
|
|
345
|
+
type: 'fieldref',
|
|
346
|
+
path: wildPath.path,
|
|
347
|
+
at: wildPath.at,
|
|
348
|
+
},
|
|
349
|
+
typeDesc,
|
|
350
|
+
});
|
|
351
|
+
nextFieldUsage = typeDesc.fieldUsage;
|
|
254
352
|
}
|
|
255
353
|
else {
|
|
256
|
-
const
|
|
257
|
-
if (
|
|
354
|
+
const queryFieldDef = field.getQueryFieldDef(this.exprSpace);
|
|
355
|
+
if (queryFieldDef) {
|
|
258
356
|
const typeDesc = field.typeDesc();
|
|
259
357
|
nextFieldUsage = typeDesc.fieldUsage;
|
|
260
358
|
// Filter out fields whose type is 'error', which means that a totally bad field
|
|
@@ -264,17 +362,13 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
264
362
|
if (typeDesc &&
|
|
265
363
|
typeDesc.type !== 'error' &&
|
|
266
364
|
this.canContain(typeDesc) &&
|
|
267
|
-
!isEmptyNest(
|
|
268
|
-
fields.push(
|
|
365
|
+
!isEmptyNest(queryFieldDef)) {
|
|
366
|
+
fields.push({ queryFieldDef, typeDesc });
|
|
269
367
|
}
|
|
270
368
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
// don't have a field def, we "know" that that field is already in the query,
|
|
275
|
-
// and we don't need to worry about actually adding it. Previously, this was also true for
|
|
276
|
-
// project statements, where we added "*" as a field and also all the individual
|
|
277
|
-
// fields, but the individual fields didn't have field defs.
|
|
369
|
+
else {
|
|
370
|
+
throw new Error('Expected query field to have a definition');
|
|
371
|
+
}
|
|
278
372
|
}
|
|
279
373
|
}
|
|
280
374
|
fieldUsage = (_a = (0, composite_source_utils_1.mergeFieldUsage)(fieldUsage, nextFieldUsage)) !== null && _a !== void 0 ? _a : [];
|
|
@@ -285,6 +379,7 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
285
379
|
drillDimension.firstDrill.logError('illegal-drill', `Must provide a value for all dimensions in a view when drilling: missing \`${drillDimension.dimensionPath.join('.')}\``);
|
|
286
380
|
}
|
|
287
381
|
}
|
|
382
|
+
this.translatedQueryFields = fields;
|
|
288
383
|
return fields;
|
|
289
384
|
}
|
|
290
385
|
getQuerySegment(rf) {
|
|
@@ -294,17 +389,24 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
294
389
|
}
|
|
295
390
|
throw new Error('TODO NOT POSSIBLE');
|
|
296
391
|
}
|
|
392
|
+
isRepeated() {
|
|
393
|
+
const fields = this.translateQueryFields();
|
|
394
|
+
const dimensions = fields.filter(f => model.TD.isAtomic(f.typeDesc) &&
|
|
395
|
+
model.expressionIsScalar(f.typeDesc.expressionType));
|
|
396
|
+
return dimensions.length > 0;
|
|
397
|
+
}
|
|
297
398
|
getPipeSegment(refineFrom) {
|
|
298
399
|
if (this.segmentType === 'index') {
|
|
299
400
|
// come coding error made this "impossible" thing happen
|
|
300
401
|
this.logError('unexpected-index-segment', 'internal error generating index segment from non index query');
|
|
301
|
-
return
|
|
402
|
+
return error_factory_1.ErrorFactory.reduceSegment;
|
|
302
403
|
}
|
|
303
404
|
const segment = {
|
|
304
405
|
type: this.segmentType,
|
|
305
406
|
queryFields: this.queryFieldDefs(),
|
|
407
|
+
outputStruct: this.structDef(),
|
|
408
|
+
isRepeated: this.isRepeated(),
|
|
306
409
|
};
|
|
307
|
-
segment.queryFields = (0, field_utils_1.mergeFields)(refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.queryFields, segment.queryFields);
|
|
308
410
|
if (refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.extendSource) {
|
|
309
411
|
segment.extendSource = refineFrom.extendSource;
|
|
310
412
|
}
|
|
@@ -331,9 +433,6 @@ class QuerySpace extends QueryOperationSpace {
|
|
|
331
433
|
}
|
|
332
434
|
return this.exprSpace.lookup(path);
|
|
333
435
|
}
|
|
334
|
-
isQueryFieldSpace() {
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
436
|
}
|
|
338
437
|
exports.QuerySpace = QuerySpace;
|
|
339
438
|
class ReduceFieldSpace extends QuerySpace {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TypeDesc, AtomicFieldDef, QueryFieldDef, TurtleDef } from '../../../model/malloy_types';
|
|
2
|
+
import type { FieldSpace } from '../types/field-space';
|
|
3
|
+
import { SpaceField } from '../types/space-field';
|
|
4
|
+
export declare class RefineFromSpaceField extends SpaceField {
|
|
5
|
+
private readonly refineFromFieldDef;
|
|
6
|
+
constructor(refineFromFieldDef: AtomicFieldDef | TurtleDef);
|
|
7
|
+
getQueryFieldDef(_fs: FieldSpace): QueryFieldDef | undefined;
|
|
8
|
+
typeDesc(): TypeDesc;
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RefineFromSpaceField = void 0;
|
|
10
|
+
const space_field_1 = require("../types/space-field");
|
|
11
|
+
class RefineFromSpaceField extends space_field_1.SpaceField {
|
|
12
|
+
constructor(refineFromFieldDef) {
|
|
13
|
+
super();
|
|
14
|
+
this.refineFromFieldDef = refineFromFieldDef;
|
|
15
|
+
}
|
|
16
|
+
getQueryFieldDef(_fs) {
|
|
17
|
+
return this.refineFromFieldDef;
|
|
18
|
+
}
|
|
19
|
+
typeDesc() {
|
|
20
|
+
return this.typeFromFieldDef(this.refineFromFieldDef);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.RefineFromSpaceField = RefineFromSpaceField;
|
|
24
|
+
//# sourceMappingURL=refine-from-space-field.js.map
|