@malloydata/malloy 0.0.402 → 0.0.404
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/foundation/core.js +6 -6
- package/dist/api/foundation/result.js +1 -2
- package/dist/dialect/dialect.d.ts +9 -4
- package/dist/dialect/dialect.js +35 -11
- package/dist/dialect/pg_impl.d.ts +1 -0
- package/dist/dialect/pg_impl.js +8 -0
- package/dist/dialect/snowflake/snowflake.js +4 -5
- package/dist/dialect/trino/trino.d.ts +1 -0
- package/dist/dialect/trino/trino.js +27 -6
- package/dist/lang/ast/expressions/expr-func.js +4 -4
- package/dist/lang/ast/field-space/dynamic-space.js +2 -2
- package/dist/lang/ast/field-space/include-utils.js +4 -4
- package/dist/lang/ast/field-space/query-spaces.js +6 -8
- package/dist/lang/ast/field-space/refined-space.js +6 -6
- package/dist/lang/ast/field-space/rename-space-field.js +6 -9
- package/dist/lang/ast/field-space/static-space.js +1 -1
- package/dist/lang/ast/field-space/struct-space-field-base.js +1 -1
- package/dist/lang/ast/query-properties/drill.js +3 -6
- package/dist/lang/ast/source-elements/composite-source.js +1 -2
- package/dist/lang/ast/source-elements/sql-source.js +6 -8
- package/dist/lang/ast/source-elements/table-source.js +8 -10
- package/dist/lang/ast/source-elements/typed-source.js +2 -3
- package/dist/lang/ast/source-properties/join.js +3 -5
- package/dist/lang/ast/source-query-elements/sq-reference.js +1 -1
- package/dist/lang/ast/statements/define-source.js +1 -1
- package/dist/lang/ast/types/malloy-element.d.ts +1 -0
- package/dist/lang/ast/types/malloy-element.js +9 -7
- package/dist/lang/composite-source-utils.js +13 -17
- package/dist/lang/field-utils.js +2 -2
- package/dist/lang/test/test-translator.js +2 -4
- package/dist/model/field_instance.js +1 -1
- package/dist/model/malloy_types.d.ts +7 -2
- package/dist/model/malloy_types.js +11 -8
- package/dist/model/query_model_impl.d.ts +0 -1
- package/dist/model/query_model_impl.js +9 -28
- package/dist/model/query_node.d.ts +1 -10
- package/dist/model/query_node.js +8 -42
- package/dist/model/query_query.js +2 -2
- package/dist/model/utils.js +3 -3
- package/dist/to_stable.js +7 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -50,7 +50,7 @@ class TypedSource extends source_1.Source {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
const isVirtual = sourceDef.type === 'virtual';
|
|
53
|
-
const sourceFields = new Map(sourceDef.fields.map(f =>
|
|
53
|
+
const sourceFields = new Map(sourceDef.fields.map(f => [(0, malloy_types_1.activeName)(f), f]));
|
|
54
54
|
const fieldsToAdd = [];
|
|
55
55
|
// Validate/Enforce that this source matches the shape
|
|
56
56
|
for (const [name, { field, fromShape }] of outputShape) {
|
|
@@ -72,8 +72,7 @@ class TypedSource extends source_1.Source {
|
|
|
72
72
|
// Intrinsic fields not in any shape: mark as hidden.
|
|
73
73
|
// Matching fields inherit annotations from the shape.
|
|
74
74
|
const resultFields = sourceDef.fields.map(f => {
|
|
75
|
-
|
|
76
|
-
const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
|
|
75
|
+
const name = (0, malloy_types_1.activeName)(f);
|
|
77
76
|
const shapeEntry = outputShape.get(name);
|
|
78
77
|
if (!shapeEntry || !(0, malloy_types_1.fieldIsIntrinsic)(f)) {
|
|
79
78
|
return (0, malloy_types_1.fieldIsIntrinsic)(f) && !shapeEntry
|
|
@@ -69,13 +69,12 @@ class KeyJoin extends Join {
|
|
|
69
69
|
}
|
|
70
70
|
const joinStruct = {
|
|
71
71
|
...sourceDef,
|
|
72
|
-
|
|
72
|
+
as: this.name.refString,
|
|
73
73
|
join: 'one',
|
|
74
74
|
matrixOperation: 'left',
|
|
75
75
|
onExpression: { node: 'error', message: "('join fixup'='not done yet')" },
|
|
76
76
|
location: this.location,
|
|
77
77
|
};
|
|
78
|
-
delete joinStruct.as;
|
|
79
78
|
if (this.note) {
|
|
80
79
|
joinStruct.annotations = this.note;
|
|
81
80
|
}
|
|
@@ -85,7 +84,7 @@ class KeyJoin extends Join {
|
|
|
85
84
|
fixupJoinOn(outer, inStruct) {
|
|
86
85
|
const exprX = this.keyExpr.getExpression(outer);
|
|
87
86
|
if ((0, malloy_types_1.isSourceDef)(inStruct) && inStruct.primaryKey) {
|
|
88
|
-
const pkey = inStruct.fields.find(f => (
|
|
87
|
+
const pkey = inStruct.fields.find(f => (0, malloy_types_1.activeName)(f) === inStruct.primaryKey);
|
|
89
88
|
if (pkey) {
|
|
90
89
|
if (pkey.type === exprX.type) {
|
|
91
90
|
const keyPath = [this.name.refString, inStruct.primaryKey];
|
|
@@ -165,12 +164,11 @@ class ExpressionJoin extends Join {
|
|
|
165
164
|
}
|
|
166
165
|
const joinStruct = {
|
|
167
166
|
...sourceDef,
|
|
168
|
-
|
|
167
|
+
as: this.name.refString,
|
|
169
168
|
join: this.joinType,
|
|
170
169
|
matrixOperation,
|
|
171
170
|
location: this.location,
|
|
172
171
|
};
|
|
173
|
-
delete joinStruct.as;
|
|
174
172
|
if (this.note) {
|
|
175
173
|
joinStruct.annotations = this.note;
|
|
176
174
|
}
|
|
@@ -52,7 +52,7 @@ class SQReference extends source_query_element_1.SourceQueryElement {
|
|
|
52
52
|
return query;
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
|
-
const label = entry.type === 'given' ? entry.name :
|
|
55
|
+
const label = entry.type === 'given' ? entry.name : (0, model_1.activeName)(entry);
|
|
56
56
|
this.sqLog('cannot-use-as-query', `Illegal reference to '${label}', query expected`);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -97,7 +97,7 @@ class DefineSource extends malloy_element_1.MalloyElement {
|
|
|
97
97
|
}
|
|
98
98
|
validateParameterShadowing(parameters, structDef) {
|
|
99
99
|
for (const parameter of parameters) {
|
|
100
|
-
if (structDef.fields.find(field =>
|
|
100
|
+
if (structDef.fields.find(field => (0, malloy_types_1.activeName)(field) === parameter.name)) {
|
|
101
101
|
parameter.logError('parameter-shadowing-field', `Illegal shadowing of field \`${parameter.name}\` by parameter with the same name`);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -238,21 +238,23 @@ class MalloyElement {
|
|
|
238
238
|
}
|
|
239
239
|
return asString;
|
|
240
240
|
}
|
|
241
|
-
*
|
|
241
|
+
*allChildren() {
|
|
242
242
|
for (const kidLabel of Object.keys(this.children)) {
|
|
243
243
|
const kiddle = this.children[kidLabel];
|
|
244
244
|
if (kiddle instanceof MalloyElement) {
|
|
245
245
|
yield kiddle;
|
|
246
|
-
yield* kiddle.walk();
|
|
247
246
|
}
|
|
248
247
|
else {
|
|
249
|
-
|
|
250
|
-
yield k;
|
|
251
|
-
yield* k.walk();
|
|
252
|
-
}
|
|
248
|
+
yield* kiddle;
|
|
253
249
|
}
|
|
254
250
|
}
|
|
255
251
|
}
|
|
252
|
+
*walk() {
|
|
253
|
+
for (const child of this.allChildren()) {
|
|
254
|
+
yield child;
|
|
255
|
+
yield* child.walk();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
256
258
|
varInfo() {
|
|
257
259
|
let extra = '';
|
|
258
260
|
for (const [key, value] of Object.entries(this)) {
|
|
@@ -271,7 +273,7 @@ class MalloyElement {
|
|
|
271
273
|
return new Error(`INTERNAL ERROR IN TRANSLATION: ${msg}`);
|
|
272
274
|
}
|
|
273
275
|
needs(doc) {
|
|
274
|
-
for (const child of this.
|
|
276
|
+
for (const child of this.allChildren()) {
|
|
275
277
|
const childNeeds = child.needs(doc);
|
|
276
278
|
if (childNeeds)
|
|
277
279
|
return childNeeds;
|
|
@@ -37,7 +37,7 @@ const annotation_1 = require("../api/foundation/annotation");
|
|
|
37
37
|
function _resolveCompositeSources(path, source, rootFields, nests, fieldUsage,
|
|
38
38
|
// for resolving nested composites; the list of sources to try
|
|
39
39
|
sources) {
|
|
40
|
-
var _a, _b, _c, _d
|
|
40
|
+
var _a, _b, _c, _d;
|
|
41
41
|
// TODO skip all this if the tree doesn't have any composite sources
|
|
42
42
|
let base = { ...source };
|
|
43
43
|
let anyComposites = false;
|
|
@@ -65,10 +65,10 @@ sources) {
|
|
|
65
65
|
const fieldNames = new Set();
|
|
66
66
|
for (const field of inputSource.fields) {
|
|
67
67
|
if (field.accessModifier !== 'private') {
|
|
68
|
-
fieldNames.add((
|
|
68
|
+
fieldNames.add((0, malloy_types_1.activeName)(field));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
const fieldUsageWithWheres = (
|
|
71
|
+
const fieldUsageWithWheres = (_a = mergeFieldUsage(getFieldUsageFromFilterList(inputSource), fieldUsage)) !== null && _a !== void 0 ? _a : [];
|
|
72
72
|
const fieldsForLookup = [...nonCompositeFields, ...inputSource.fields];
|
|
73
73
|
const expanded = expandRefUsage({ fieldUsage: fieldUsageWithWheres }, fieldsForLookup);
|
|
74
74
|
if (expanded.missingFields.length > 0) {
|
|
@@ -129,7 +129,7 @@ sources) {
|
|
|
129
129
|
...base,
|
|
130
130
|
fields,
|
|
131
131
|
arguments: source.arguments,
|
|
132
|
-
filterList: [...((
|
|
132
|
+
filterList: [...((_b = source.filterList) !== null && _b !== void 0 ? _b : []), ...((_c = base.filterList) !== null && _c !== void 0 ? _c : [])],
|
|
133
133
|
};
|
|
134
134
|
const joinError = processJoins(path, base, rootFields, nests, expandedCategorized);
|
|
135
135
|
// Fourth point where we abort: if a join failed
|
|
@@ -199,7 +199,7 @@ sources) {
|
|
|
199
199
|
}
|
|
200
200
|
base = {
|
|
201
201
|
...source,
|
|
202
|
-
filterList: [...((
|
|
202
|
+
filterList: [...((_d = source.filterList) !== null && _d !== void 0 ? _d : []), partitionFilter],
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
205
|
if (!joinsProcessed) {
|
|
@@ -579,12 +579,12 @@ function getPartitionCompositeDesc(annotations, structDef, logTo) {
|
|
|
579
579
|
partitions.push({ id, fields });
|
|
580
580
|
}
|
|
581
581
|
for (const field of [partitionField, ...allFields]) {
|
|
582
|
-
const def = structDef.fields.find(f =>
|
|
582
|
+
const def = structDef.fields.find(f => (0, malloy_types_1.activeName)(f) === field);
|
|
583
583
|
if (def === undefined) {
|
|
584
584
|
logTo.logError('invalid-partition-composite', `Composite partition field \`${field}\` not present in source`);
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
|
-
const compositeFields = structDef.fields.map(f =>
|
|
587
|
+
const compositeFields = structDef.fields.map(f => (0, malloy_types_1.activeName)(f));
|
|
588
588
|
return { partitionField, partitions, compositeFields };
|
|
589
589
|
}
|
|
590
590
|
function composeAnnotations(base, slice) {
|
|
@@ -602,17 +602,15 @@ function composeAnnotations(base, slice) {
|
|
|
602
602
|
};
|
|
603
603
|
}
|
|
604
604
|
function mergeFields(...fields) {
|
|
605
|
-
var _a;
|
|
606
605
|
const fieldsByName = {};
|
|
607
606
|
for (const list of fields) {
|
|
608
607
|
for (const field of list) {
|
|
609
|
-
fieldsByName[(
|
|
608
|
+
fieldsByName[(0, malloy_types_1.activeName)(field)] = field;
|
|
610
609
|
}
|
|
611
610
|
}
|
|
612
611
|
return Object.values(fieldsByName);
|
|
613
612
|
}
|
|
614
613
|
function genRootFields(rootFields, joinPath, fields, replace = true) {
|
|
615
|
-
var _a;
|
|
616
614
|
if (joinPath.length === 0) {
|
|
617
615
|
if (replace)
|
|
618
616
|
return [...fields];
|
|
@@ -621,7 +619,7 @@ function genRootFields(rootFields, joinPath, fields, replace = true) {
|
|
|
621
619
|
const headJoinName = joinPath[0];
|
|
622
620
|
const fieldsByName = {};
|
|
623
621
|
for (const field of rootFields) {
|
|
624
|
-
fieldsByName[(
|
|
622
|
+
fieldsByName[(0, malloy_types_1.activeName)(field)] = field;
|
|
625
623
|
}
|
|
626
624
|
const join = fieldsByName[headJoinName];
|
|
627
625
|
if (join === undefined) {
|
|
@@ -649,12 +647,11 @@ function getJoinFields(rootFields, joinPath) {
|
|
|
649
647
|
// Updating its `fields` list with the resolved joins
|
|
650
648
|
// And updating `narrowedJoinedSources` with the narrowed sources for each join
|
|
651
649
|
function processJoins(path, base, rootFields, nests, categorizedFieldUsage) {
|
|
652
|
-
var _a, _b;
|
|
653
650
|
let anyComposites = false;
|
|
654
651
|
const fieldsByName = {};
|
|
655
652
|
const errors = [];
|
|
656
653
|
for (const field of base.fields) {
|
|
657
|
-
fieldsByName[(
|
|
654
|
+
fieldsByName[(0, malloy_types_1.activeName)(field)] = field;
|
|
658
655
|
}
|
|
659
656
|
for (const [joinName, joinedUsage] of Object.entries(categorizedFieldUsage.joinUsage)) {
|
|
660
657
|
const newPath = [...path, joinName];
|
|
@@ -708,7 +705,7 @@ function processJoins(path, base, rootFields, nests, categorizedFieldUsage) {
|
|
|
708
705
|
fieldsByName[joinName] = {
|
|
709
706
|
...resolved.success,
|
|
710
707
|
join: join.join,
|
|
711
|
-
as: (
|
|
708
|
+
as: (0, malloy_types_1.activeName)(join),
|
|
712
709
|
onExpression: join.onExpression,
|
|
713
710
|
};
|
|
714
711
|
base.fields = Object.values(fieldsByName);
|
|
@@ -1294,13 +1291,12 @@ function pathBegins(path, prefix) {
|
|
|
1294
1291
|
return path.length >= prefix.length && prefix.every((s, i) => path[i] === s);
|
|
1295
1292
|
}
|
|
1296
1293
|
function buildNamespace(fields) {
|
|
1297
|
-
var _a;
|
|
1298
1294
|
const namespace = {
|
|
1299
1295
|
fields: {},
|
|
1300
1296
|
nested: {},
|
|
1301
1297
|
};
|
|
1302
1298
|
for (const field of fields) {
|
|
1303
|
-
const name = (
|
|
1299
|
+
const name = (0, malloy_types_1.activeName)(field);
|
|
1304
1300
|
namespace.fields[name] = field;
|
|
1305
1301
|
// If it's a join with nested fields, recursively build its hierarchy
|
|
1306
1302
|
if ((0, malloy_types_1.isJoined)(field) && field.fields) {
|
|
@@ -1325,7 +1321,7 @@ function inNamespace(path, space) {
|
|
|
1325
1321
|
}
|
|
1326
1322
|
function lookup(field, fields) {
|
|
1327
1323
|
const [head, ...rest] = field;
|
|
1328
|
-
const def = fields.find(f =>
|
|
1324
|
+
const def = fields.find(f => (0, malloy_types_1.activeName)(f) === head);
|
|
1329
1325
|
if (def === undefined) {
|
|
1330
1326
|
throw new Error(`No definition for ${head} when resolving composite source`);
|
|
1331
1327
|
}
|
package/dist/lang/field-utils.js
CHANGED
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.nameFromDef = nameFromDef;
|
|
26
26
|
exports.mergeFields = mergeFields;
|
|
27
|
+
const malloy_types_1 = require("../model/malloy_types");
|
|
27
28
|
function nameFromDef(f1) {
|
|
28
|
-
var _a;
|
|
29
29
|
if (f1.type === 'fieldref') {
|
|
30
30
|
return f1.path[f1.path.length - 1];
|
|
31
31
|
}
|
|
32
|
-
return (
|
|
32
|
+
return (0, malloy_types_1.activeName)(f1);
|
|
33
33
|
}
|
|
34
34
|
function mergeFields(older, newer) {
|
|
35
35
|
if (older === undefined) {
|
|
@@ -583,16 +583,14 @@ function getModelQuery(modelDef, name) {
|
|
|
583
583
|
return modelDef.contents[name];
|
|
584
584
|
}
|
|
585
585
|
function getFieldDef(source, name) {
|
|
586
|
-
var _a;
|
|
587
586
|
for (const f of source.fields) {
|
|
588
|
-
if ((
|
|
587
|
+
if ((0, malloy_types_1.activeName)(f) === name) {
|
|
589
588
|
return f;
|
|
590
589
|
}
|
|
591
590
|
}
|
|
592
591
|
throw new Error(`Compiled source did not contain expected field '${name}'`);
|
|
593
592
|
}
|
|
594
593
|
function getQueryFieldDef(query, name) {
|
|
595
|
-
var _a;
|
|
596
594
|
if ((0, malloy_types_1.isQuerySegment)(query)) {
|
|
597
595
|
for (const f of query.queryFields) {
|
|
598
596
|
if (f.type === 'fieldref') {
|
|
@@ -600,7 +598,7 @@ function getQueryFieldDef(query, name) {
|
|
|
600
598
|
return f;
|
|
601
599
|
}
|
|
602
600
|
}
|
|
603
|
-
else if ((
|
|
601
|
+
else if ((0, malloy_types_1.activeName)(f) === name) {
|
|
604
602
|
return f;
|
|
605
603
|
}
|
|
606
604
|
}
|
|
@@ -59,7 +59,7 @@ class FieldInstanceField {
|
|
|
59
59
|
var _a;
|
|
60
60
|
if (this.f.parent.primaryKey()) {
|
|
61
61
|
const pk = this.f.parent.getPrimaryKeyField(this.f.fieldDef);
|
|
62
|
-
const pkName =
|
|
62
|
+
const pkName = (0, malloy_types_1.activeName)(pk.fieldDef);
|
|
63
63
|
const pkField = this.parent.getField(pkName);
|
|
64
64
|
return pkField.generateExpression();
|
|
65
65
|
}
|
|
@@ -444,6 +444,13 @@ export interface AliasedName {
|
|
|
444
444
|
name: string;
|
|
445
445
|
as?: string;
|
|
446
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* The name an `AliasedName` goes by in its current context: its `as` binding
|
|
449
|
+
* if it has one, otherwise its intrinsic `name`. This is the only correct way
|
|
450
|
+
* to ask "what is this called here" — see the `name`/`as` invariant in
|
|
451
|
+
* model/CONTEXT.md.
|
|
452
|
+
*/
|
|
453
|
+
export declare function activeName(an: AliasedName): string;
|
|
447
454
|
/** all named objects have a type an a name (optionally aliased) */
|
|
448
455
|
export interface NamedObject extends AliasedName, HasLocation {
|
|
449
456
|
type: string;
|
|
@@ -1092,8 +1099,6 @@ export interface RefToField extends HasAnnotations {
|
|
|
1092
1099
|
}
|
|
1093
1100
|
export type QueryFieldDef = AtomicFieldDef | TurtleDef | RefToField;
|
|
1094
1101
|
export type TypedDef = AtomicTypeDef | JoinFieldDef | TurtleDef | RefToField | StructDef;
|
|
1095
|
-
/** Get the output name for a NamedObject */
|
|
1096
|
-
export declare function getIdentifier(n: AliasedName): string;
|
|
1097
1102
|
export interface UserTypeFieldDef extends HasAnnotations {
|
|
1098
1103
|
name: string;
|
|
1099
1104
|
typeDef: AtomicTypeDef;
|
|
@@ -36,6 +36,7 @@ exports.isFilterExprType = isFilterExprType;
|
|
|
36
36
|
exports.isTimeLiteral = isTimeLiteral;
|
|
37
37
|
exports.isParameterType = isParameterType;
|
|
38
38
|
exports.paramHasValue = paramHasValue;
|
|
39
|
+
exports.activeName = activeName;
|
|
39
40
|
exports.expressionIsScalar = expressionIsScalar;
|
|
40
41
|
exports.expressionIsAggregate = expressionIsAggregate;
|
|
41
42
|
exports.expressionIsUngroupedAggregate = expressionIsUngroupedAggregate;
|
|
@@ -93,7 +94,6 @@ exports.isBaseTable = isBaseTable;
|
|
|
93
94
|
exports.isLiteral = isLiteral;
|
|
94
95
|
exports.mergeEvalSpaces = mergeEvalSpaces;
|
|
95
96
|
exports.isBasicAtomic = isBasicAtomic;
|
|
96
|
-
exports.getIdentifier = getIdentifier;
|
|
97
97
|
exports.isUserTypeDef = isUserTypeDef;
|
|
98
98
|
exports.isCompoundArrayData = isCompoundArrayData;
|
|
99
99
|
exports.isTurtle = isTurtle;
|
|
@@ -183,6 +183,16 @@ function isParameterType(t) {
|
|
|
183
183
|
function paramHasValue(p) {
|
|
184
184
|
return p.value !== null;
|
|
185
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The name an `AliasedName` goes by in its current context: its `as` binding
|
|
188
|
+
* if it has one, otherwise its intrinsic `name`. This is the only correct way
|
|
189
|
+
* to ask "what is this called here" — see the `name`/`as` invariant in
|
|
190
|
+
* model/CONTEXT.md.
|
|
191
|
+
*/
|
|
192
|
+
function activeName(an) {
|
|
193
|
+
var _a;
|
|
194
|
+
return (_a = an.as) !== null && _a !== void 0 ? _a : an.name;
|
|
195
|
+
}
|
|
186
196
|
function expressionIsScalar(e) {
|
|
187
197
|
return e === undefined || e === 'scalar';
|
|
188
198
|
}
|
|
@@ -580,13 +590,6 @@ function isBasicAtomic(fd) {
|
|
|
580
590
|
fd.type === 'sql native' ||
|
|
581
591
|
fd.type === 'error');
|
|
582
592
|
}
|
|
583
|
-
/** Get the output name for a NamedObject */
|
|
584
|
-
function getIdentifier(n) {
|
|
585
|
-
if (n.as !== undefined) {
|
|
586
|
-
return n.as;
|
|
587
|
-
}
|
|
588
|
-
return n.name;
|
|
589
|
-
}
|
|
590
593
|
function isUserTypeDef(sd) {
|
|
591
594
|
return sd.type === 'userType';
|
|
592
595
|
}
|
|
@@ -12,7 +12,6 @@ export declare class QueryModelImpl implements QueryModel, ModelRootInterface {
|
|
|
12
12
|
structs: Map<string, QueryStruct>;
|
|
13
13
|
get givens(): Record<string, Given>;
|
|
14
14
|
constructor(modelDef: ModelDef | undefined);
|
|
15
|
-
getFinalOutputStruct(query: Query, options: PrepareResultOptions | undefined): SourceDef | undefined;
|
|
16
15
|
loadModelFromDef(modelDef: ModelDef): void;
|
|
17
16
|
getStructByName(name: string): QueryStruct;
|
|
18
17
|
getStructFromRef(structRef: StructRef, sourceArguments: Record<string, Argument> | undefined, prepareResultOptions?: PrepareResultOptions): QueryStruct;
|
|
@@ -33,31 +33,17 @@ class QueryModelImpl {
|
|
|
33
33
|
this.loadModelFromDef(modelDef);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
// Another circularity breaking method ... call into QueryQuery
|
|
37
|
-
// to find the output shape of a query
|
|
38
|
-
getFinalOutputStruct(query, options) {
|
|
39
|
-
const result = this.loadQuery(query, undefined, options, false, false);
|
|
40
|
-
return result.structs.pop();
|
|
41
|
-
}
|
|
42
36
|
loadModelFromDef(modelDef) {
|
|
43
37
|
this.modelDef = modelDef;
|
|
44
38
|
for (const s of Object.values(this.modelDef.contents)) {
|
|
45
|
-
|
|
39
|
+
// Only sources become QueryStructs. query/userType/given are namespace
|
|
40
|
+
// metadata, not queryable, and are skipped.
|
|
46
41
|
if ((0, malloy_types_1.isSourceDef)(s)) {
|
|
47
|
-
|
|
48
|
-
this.structs.set((0, malloy_types_1.getIdentifier)(s), qs);
|
|
49
|
-
qs.resolveQueryFields((query, options) => this.getFinalOutputStruct(query, options));
|
|
50
|
-
}
|
|
51
|
-
else if (s.type === 'query') {
|
|
52
|
-
/* TODO */
|
|
53
|
-
}
|
|
54
|
-
else if (s.type === 'userType') {
|
|
55
|
-
// User type definitions are metadata only, not queryable
|
|
42
|
+
this.structs.set((0, malloy_types_1.activeName)(s), new query_node_1.QueryStruct(s, undefined, { model: this }, {}));
|
|
56
43
|
}
|
|
57
|
-
else if (s.type
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
else {
|
|
44
|
+
else if (s.type !== 'query' &&
|
|
45
|
+
s.type !== 'userType' &&
|
|
46
|
+
s.type !== 'given') {
|
|
61
47
|
throw new Error('Internal Error: Unknown structure type');
|
|
62
48
|
}
|
|
63
49
|
}
|
|
@@ -73,10 +59,7 @@ class QueryModelImpl {
|
|
|
73
59
|
prepareResultOptions !== null && prepareResultOptions !== void 0 ? prepareResultOptions : (prepareResultOptions = {});
|
|
74
60
|
if (typeof structRef === 'string') {
|
|
75
61
|
const ret = this.getStructByName(structRef);
|
|
76
|
-
|
|
77
|
-
return new query_node_1.QueryStruct(ret.structDef, sourceArguments, ret.parent ? { struct: ret.parent } : { model: this }, prepareResultOptions);
|
|
78
|
-
}
|
|
79
|
-
return ret;
|
|
62
|
+
return new query_node_1.QueryStruct(ret.structDef, sourceArguments !== null && sourceArguments !== void 0 ? sourceArguments : ret.sourceArguments, ret.parent ? { struct: ret.parent } : { model: this }, prepareResultOptions);
|
|
80
63
|
}
|
|
81
64
|
return new query_node_1.QueryStruct(structRef, sourceArguments, { model: this }, prepareResultOptions);
|
|
82
65
|
}
|
|
@@ -103,7 +86,7 @@ class QueryModelImpl {
|
|
|
103
86
|
if (emitFinalStage && q.parent.dialect.hasFinalStage) {
|
|
104
87
|
// const fieldNames: string[] = [];
|
|
105
88
|
// for (const f of ret.outputStruct.fields) {
|
|
106
|
-
// fieldNames.push(
|
|
89
|
+
// fieldNames.push(activeName(f));
|
|
107
90
|
// }
|
|
108
91
|
const fieldNames = [];
|
|
109
92
|
for (const f of ret.outputStruct.fields) {
|
|
@@ -156,9 +139,7 @@ class QueryModelImpl {
|
|
|
156
139
|
const addedDefaultRowLimit = addDefaultRowLimit.addedDefaultRowLimit;
|
|
157
140
|
const ret = this.loadQuery(query, undefined, prepareResultOptions, finalize, false);
|
|
158
141
|
const structRef = (_a = query.compositeResolvedSourceDef) !== null && _a !== void 0 ? _a : query.structRef;
|
|
159
|
-
const sourceExplore = typeof structRef === 'string'
|
|
160
|
-
? structRef
|
|
161
|
-
: structRef.as || structRef.name;
|
|
142
|
+
const sourceExplore = typeof structRef === 'string' ? structRef : (0, malloy_types_1.activeName)(structRef);
|
|
162
143
|
const sourceArguments = (_b = query.sourceArguments) !== null && _b !== void 0 ? _b : (typeof structRef === 'string' ? undefined : structRef.arguments);
|
|
163
144
|
// LTNote: I don't understand why this might be here. It should have happened in loadQuery...
|
|
164
145
|
if (finalize && this.dialect.hasFinalStage) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FieldDef, BooleanFieldDef, DateFieldDef, DocumentLocation, StringFieldDef, JSONFieldDef, NumberFieldDef, ATimestampFieldDef, NativeUnsupportedFieldDef, JoinFieldDef, Argument, Given, GivenID, PrepareResultOptions, AtomicFieldDef, BasicAtomicDef, FilterCondition, RefToField, StructDef, TurtleDef, TurtleDefPlusFilters
|
|
1
|
+
import type { FieldDef, BooleanFieldDef, DateFieldDef, DocumentLocation, StringFieldDef, JSONFieldDef, NumberFieldDef, ATimestampFieldDef, NativeUnsupportedFieldDef, JoinFieldDef, Argument, Given, GivenID, PrepareResultOptions, AtomicFieldDef, BasicAtomicDef, FilterCondition, RefToField, StructDef, TurtleDef, TurtleDefPlusFilters } from './malloy_types';
|
|
2
2
|
import type { EventStream } from '../runtime_types';
|
|
3
3
|
import type { Tag } from '@malloydata/malloy-tag';
|
|
4
4
|
import type { Dialect } from '../dialect';
|
|
@@ -109,15 +109,6 @@ export declare class QueryStruct {
|
|
|
109
109
|
addFieldToNameMap(as: string, n: QueryField, at?: DocumentLocation): void;
|
|
110
110
|
/** the the primary key or throw an error. */
|
|
111
111
|
getPrimaryKeyField(fieldDef: FieldDef): QueryBasicField;
|
|
112
|
-
/**
|
|
113
|
-
* called after all structure has been loaded. Examine this structure to see
|
|
114
|
-
* if if it is based on a query and if it is, add the output fields (unless
|
|
115
|
-
* they exist) to the structure.
|
|
116
|
-
*
|
|
117
|
-
* finalOutputStruct exists so that query_node doesn't need to
|
|
118
|
-
* to import query_query
|
|
119
|
-
*/
|
|
120
|
-
resolveQueryFields(finalOutputStruct: (query: Query, options: PrepareResultOptions | undefined) => SourceDef | undefined): void;
|
|
121
112
|
getModel(): ModelRootInterface;
|
|
122
113
|
get eventStream(): EventStream | undefined;
|
|
123
114
|
/** makes a new queryable field object from a fieldDef */
|
package/dist/model/query_node.js
CHANGED
|
@@ -33,7 +33,7 @@ class QueryField extends QueryNode {
|
|
|
33
33
|
this.fieldDef = fieldDef;
|
|
34
34
|
}
|
|
35
35
|
getIdentifier() {
|
|
36
|
-
return (0, malloy_types_1.
|
|
36
|
+
return (0, malloy_types_1.activeName)(this.fieldDef);
|
|
37
37
|
}
|
|
38
38
|
getJoinableParent() {
|
|
39
39
|
const parent = this.parent;
|
|
@@ -281,7 +281,7 @@ class QueryStruct {
|
|
|
281
281
|
}
|
|
282
282
|
addFieldsFromFieldList(fields) {
|
|
283
283
|
for (const field of fields) {
|
|
284
|
-
const as = (0, malloy_types_1.
|
|
284
|
+
const as = (0, malloy_types_1.activeName)(field);
|
|
285
285
|
if (field.type === 'turtle') {
|
|
286
286
|
if (!QueryStruct.turtleFieldMaker) {
|
|
287
287
|
throw new Error('INTERNAL ERROR: QueryQuery must initialize QueryStruct nested factory method');
|
|
@@ -313,7 +313,7 @@ class QueryStruct {
|
|
|
313
313
|
// make a unique alias name
|
|
314
314
|
if (ret === undefined) {
|
|
315
315
|
const aliases = Array.from(this.pathAliasMap.values());
|
|
316
|
-
const base = identifierNormalize((0, malloy_types_1.
|
|
316
|
+
const base = identifierNormalize((0, malloy_types_1.activeName)(this.structDef));
|
|
317
317
|
let name = `${base}_0`;
|
|
318
318
|
let n = 1;
|
|
319
319
|
while (aliases.includes(name) && n < 1000) {
|
|
@@ -338,7 +338,7 @@ class QueryStruct {
|
|
|
338
338
|
if (this.unnestWithNumbers() && this.parent !== undefined) {
|
|
339
339
|
const x = this.parent.getSQLIdentifier() +
|
|
340
340
|
'.' +
|
|
341
|
-
(0, malloy_types_1.
|
|
341
|
+
(0, malloy_types_1.activeName)(this.structDef) +
|
|
342
342
|
`[${this.getIdentifier()}.__row_id]`;
|
|
343
343
|
return x;
|
|
344
344
|
}
|
|
@@ -386,7 +386,7 @@ class QueryStruct {
|
|
|
386
386
|
}
|
|
387
387
|
// if this is an inline object, include the parents alias.
|
|
388
388
|
if (this.structDef.type === 'record' && this.parent) {
|
|
389
|
-
return this.parent.sqlSimpleChildReference((0, malloy_types_1.
|
|
389
|
+
return this.parent.sqlSimpleChildReference((0, malloy_types_1.activeName)(this.structDef));
|
|
390
390
|
}
|
|
391
391
|
// we are somewhere in the join tree. Make sure the alias is unique.
|
|
392
392
|
return this.getAliasIdentifier();
|
|
@@ -394,7 +394,7 @@ class QueryStruct {
|
|
|
394
394
|
// return the name of the field in Malloy
|
|
395
395
|
getFullOutputName() {
|
|
396
396
|
if (this.parent) {
|
|
397
|
-
return
|
|
397
|
+
return this.parent.getFullOutputName() + (0, malloy_types_1.activeName)(this.structDef) + '.';
|
|
398
398
|
}
|
|
399
399
|
else {
|
|
400
400
|
return '';
|
|
@@ -428,45 +428,11 @@ class QueryStruct {
|
|
|
428
428
|
return pk;
|
|
429
429
|
}
|
|
430
430
|
else {
|
|
431
|
-
throw new malloy_compile_error_1.MalloyCompileError(`Source '${(0, malloy_types_1.
|
|
432
|
-
`cannot compute a unique key for field '${(0, malloy_types_1.
|
|
431
|
+
throw new malloy_compile_error_1.MalloyCompileError(`Source '${(0, malloy_types_1.activeName)(this.structDef)}' has no primary key; ` +
|
|
432
|
+
`cannot compute a unique key for field '${(0, malloy_types_1.activeName)(fieldDef)}'. ` +
|
|
433
433
|
'Add `primary_key: <field>` to the source definition.', 'compiler-missing-primary-key', fieldDef.location);
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
|
-
/**
|
|
437
|
-
* called after all structure has been loaded. Examine this structure to see
|
|
438
|
-
* if if it is based on a query and if it is, add the output fields (unless
|
|
439
|
-
* they exist) to the structure.
|
|
440
|
-
*
|
|
441
|
-
* finalOutputStruct exists so that query_node doesn't need to
|
|
442
|
-
* to import query_query
|
|
443
|
-
*/
|
|
444
|
-
resolveQueryFields(finalOutputStruct) {
|
|
445
|
-
if (this.structDef.type === 'query_source' && finalOutputStruct) {
|
|
446
|
-
const resultStruct = finalOutputStruct(this.structDef.query, this.prepareResultOptions);
|
|
447
|
-
// should never happen.
|
|
448
|
-
if (!resultStruct) {
|
|
449
|
-
throw new Error("Internal Error, query didn't produce a struct");
|
|
450
|
-
}
|
|
451
|
-
const structDef = { ...this.structDef };
|
|
452
|
-
for (const f of resultStruct.fields) {
|
|
453
|
-
const as = (0, malloy_types_1.getIdentifier)(f);
|
|
454
|
-
if (!this.nameMap.has(as)) {
|
|
455
|
-
structDef.fields.push(f);
|
|
456
|
-
this.nameMap.set(as, this.makeQueryField(f));
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
this.structDef = structDef;
|
|
460
|
-
if (!this.structDef.primaryKey && resultStruct.primaryKey) {
|
|
461
|
-
this.structDef.primaryKey = resultStruct.primaryKey;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
for (const [, v] of this.nameMap) {
|
|
465
|
-
if (v instanceof QueryFieldStruct) {
|
|
466
|
-
v.queryStruct.resolveQueryFields(finalOutputStruct);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
436
|
getModel() {
|
|
471
437
|
if (this.model) {
|
|
472
438
|
return this.model;
|
|
@@ -580,7 +580,7 @@ class QueryQuery extends query_node_1.QueryField {
|
|
|
580
580
|
return ret.lastStageName;
|
|
581
581
|
}
|
|
582
582
|
default:
|
|
583
|
-
throw new Error(`Cannot create SQL StageWriter from '${(0, malloy_types_1.
|
|
583
|
+
throw new Error(`Cannot create SQL StageWriter from '${(0, malloy_types_1.activeName)(qs.structDef)}' type '${qs.structDef.type}`);
|
|
584
584
|
}
|
|
585
585
|
}
|
|
586
586
|
/**
|
|
@@ -635,7 +635,7 @@ class QueryQuery extends query_node_1.QueryField {
|
|
|
635
635
|
let s = '';
|
|
636
636
|
const qs = ji.queryStruct;
|
|
637
637
|
const qsDef = qs.structDef;
|
|
638
|
-
(_a = qs.eventStream) === null || _a === void 0 ? void 0 : _a.emit('join-used', { name: (0, malloy_types_1.
|
|
638
|
+
(_a = qs.eventStream) === null || _a === void 0 ? void 0 : _a.emit('join-used', { name: (0, malloy_types_1.activeName)(qsDef) });
|
|
639
639
|
qs.maybeEmitParameterizedSourceUsage();
|
|
640
640
|
if ((0, malloy_types_1.isJoinedSource)(qsDef)) {
|
|
641
641
|
let structSQL = this.getStructSourceSQL(qs, stageWriter);
|
package/dist/model/utils.js
CHANGED
|
@@ -270,9 +270,9 @@ function getDialectFieldList(structDef) {
|
|
|
270
270
|
for (const f of structDef.fields.filter(malloy_types_1.fieldIsIntrinsic)) {
|
|
271
271
|
dialectFieldList.push({
|
|
272
272
|
typeDef: f,
|
|
273
|
-
sqlExpression: (0, malloy_types_1.
|
|
274
|
-
rawName: (0, malloy_types_1.
|
|
275
|
-
sqlOutputName: (0, malloy_types_1.
|
|
273
|
+
sqlExpression: (0, malloy_types_1.activeName)(f),
|
|
274
|
+
rawName: (0, malloy_types_1.activeName)(f),
|
|
275
|
+
sqlOutputName: (0, malloy_types_1.activeName)(f),
|
|
276
276
|
});
|
|
277
277
|
}
|
|
278
278
|
return dialectFieldList;
|