@malloydata/malloy 0.0.101-dev231109201517 → 0.0.101-dev231110210501
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/lang/ast/expressions/expr-id-reference.js +4 -3
- package/dist/lang/ast/field-space/column-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/column-space-field.js +1 -1
- package/dist/lang/ast/field-space/join-space-field.d.ts +1 -3
- package/dist/lang/ast/field-space/join-space-field.js +1 -2
- package/dist/lang/ast/field-space/query-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/query-space-field.js +1 -1
- package/dist/lang/ast/field-space/query-spaces.d.ts +0 -2
- package/dist/lang/ast/field-space/query-spaces.js +4 -9
- package/dist/lang/ast/field-space/reference-field.d.ts +1 -1
- package/dist/lang/ast/field-space/reference-field.js +2 -2
- package/dist/lang/ast/field-space/rename-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/rename-space-field.js +1 -1
- package/dist/lang/ast/field-space/static-space.js +1 -1
- package/dist/lang/ast/field-space/struct-space-field-base.d.ts +1 -1
- package/dist/lang/ast/field-space/struct-space-field-base.js +1 -1
- package/dist/lang/ast/field-space/wild-space-field.d.ts +1 -1
- package/dist/lang/ast/field-space/wild-space-field.js +1 -1
- package/dist/lang/ast/query-items/field-declaration.d.ts +1 -1
- package/dist/lang/ast/query-items/field-declaration.js +1 -1
- package/dist/lang/ast/query-properties/joins.js +1 -1
- package/dist/lang/ast/query-properties/ordering.js +3 -3
- package/dist/lang/ast/query-properties/qop-desc.js +1 -1
- package/dist/lang/ast/query-properties/refinements.js +1 -1
- package/dist/lang/ast/query-properties/top.js +3 -3
- package/dist/lang/ast/types/lookup-result.d.ts +1 -0
- package/dist/lang/ast/types/space-entry.d.ts +1 -8
- package/dist/lang/ast/types/space-entry.js +0 -13
- package/dist/lang/ast/types/space-param.d.ts +2 -2
- package/dist/lang/ast/types/space-param.js +2 -2
- package/dist/lang/test/lenses.spec.js +17 -2
- package/dist/lang/test/source.spec.js +44 -0
- package/package.json +1 -1
|
@@ -40,14 +40,15 @@ class ExprIdReference extends expression_def_1.ExpressionDef {
|
|
|
40
40
|
getExpression(fs) {
|
|
41
41
|
const def = this.fieldReference.getField(fs);
|
|
42
42
|
if (def.found) {
|
|
43
|
-
|
|
43
|
+
const td = def.found.typeDesc();
|
|
44
|
+
if (def.isOutputField) {
|
|
44
45
|
return {
|
|
45
|
-
...
|
|
46
|
+
...td,
|
|
47
|
+
evalSpace: td.evalSpace === 'constant' ? 'constant' : 'output',
|
|
46
48
|
value: [{ type: 'outputField', name: this.refString }],
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
51
|
const value = [{ type: def.found.refType, path: this.refString }];
|
|
50
|
-
const td = def.found.typeDesc();
|
|
51
52
|
// We think that aggregates are more 'output' like, but maybe we will reconsider that...
|
|
52
53
|
const evalSpace = (0, malloy_types_1.expressionIsAggregate)(td.expressionType)
|
|
53
54
|
? 'output'
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { FieldSpace } from '../types/field-space';
|
|
2
1
|
import { Join } from '../query-properties/joins';
|
|
3
2
|
import { StructSpaceField } from './static-space';
|
|
4
3
|
export declare class JoinSpaceField extends StructSpaceField {
|
|
5
|
-
readonly intoFS: FieldSpace;
|
|
6
4
|
readonly join: Join;
|
|
7
|
-
constructor(
|
|
5
|
+
constructor(join: Join);
|
|
8
6
|
}
|
|
@@ -25,9 +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(
|
|
28
|
+
constructor(join) {
|
|
29
29
|
super(join.structDef());
|
|
30
|
-
this.intoFS = intoFS;
|
|
31
30
|
this.join = join;
|
|
32
31
|
}
|
|
33
32
|
}
|
|
@@ -5,7 +5,6 @@ import { WildcardFieldReference } from '../query-items/field-references';
|
|
|
5
5
|
import { RefinedSpace } from './refined-space';
|
|
6
6
|
import { LookupResult } from '../types/lookup-result';
|
|
7
7
|
import { QueryInputSpace } from './query-input-space';
|
|
8
|
-
import { SpaceEntry } from '../types/space-entry';
|
|
9
8
|
/**
|
|
10
9
|
* The output space of a query operation, it is not named "QueryOutputSpace"
|
|
11
10
|
* because this is the namespace of the Query. This is the one which is constructed
|
|
@@ -22,7 +21,6 @@ export declare abstract class QuerySpace extends RefinedSpace implements QueryFi
|
|
|
22
21
|
private addRefineFromFields;
|
|
23
22
|
log(s: string): void;
|
|
24
23
|
pushFields(...defs: MalloyElement[]): void;
|
|
25
|
-
setEntry(name: string, value: SpaceEntry): void;
|
|
26
24
|
protected addWild(wild: WildcardFieldReference): void;
|
|
27
25
|
/**
|
|
28
26
|
* Check for the definition of an ungrouping reference in the result space,
|
|
@@ -110,11 +110,6 @@ class QuerySpace extends refined_space_1.RefinedSpace {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
setEntry(name, value) {
|
|
114
|
-
super.setEntry(name, value);
|
|
115
|
-
// Everything in this namespace is an output field
|
|
116
|
-
value.outputField = true;
|
|
117
|
-
}
|
|
118
113
|
addWild(wild) {
|
|
119
114
|
var _a;
|
|
120
115
|
let current = this.exprSpace;
|
|
@@ -219,9 +214,9 @@ class QuerySpace extends refined_space_1.RefinedSpace {
|
|
|
219
214
|
// (see creation of a QuerySpace) we add references to all the fields from
|
|
220
215
|
// the refinement, but they don't have definitions. So in the case where we
|
|
221
216
|
// don't have a field def, we "know" that that field is already in the query,
|
|
222
|
-
// and we don't need to worry about actually adding it.
|
|
223
|
-
// project statements, where we
|
|
224
|
-
// fields, but the individual fields
|
|
217
|
+
// and we don't need to worry about actually adding it. Previously, this was also true for
|
|
218
|
+
// project statements, where we added "*" as a field and also all the individual
|
|
219
|
+
// fields, but the individual fields didn't have field defs.
|
|
225
220
|
}
|
|
226
221
|
}
|
|
227
222
|
this.isComplete();
|
|
@@ -272,7 +267,7 @@ class QuerySpace extends refined_space_1.RefinedSpace {
|
|
|
272
267
|
lookup(path) {
|
|
273
268
|
const result = super.lookup(path);
|
|
274
269
|
if (result.found) {
|
|
275
|
-
return result;
|
|
270
|
+
return { ...result, isOutputField: true };
|
|
276
271
|
}
|
|
277
272
|
return this.exprSpace.lookup(path);
|
|
278
273
|
}
|
|
@@ -13,7 +13,7 @@ export declare class ReferenceField extends SpaceField {
|
|
|
13
13
|
constructor(fieldRef: FieldReference, inFS: FieldSpace);
|
|
14
14
|
get referenceTo(): SpaceEntry | undefined;
|
|
15
15
|
getQueryFieldDef(fs: FieldSpace): QueryFieldDef | undefined;
|
|
16
|
-
|
|
16
|
+
typeDesc(): TypeDesc;
|
|
17
17
|
/**
|
|
18
18
|
* If the referenced field has any annotations, replace the reference
|
|
19
19
|
* with something which can hold an annotation
|
|
@@ -49,12 +49,12 @@ class ReferenceField extends space_field_1.SpaceField {
|
|
|
49
49
|
}
|
|
50
50
|
return this.queryFieldDef;
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
typeDesc() {
|
|
53
53
|
if (this.memoTypeDesc)
|
|
54
54
|
return this.memoTypeDesc;
|
|
55
55
|
const refTo = this.referenceTo;
|
|
56
56
|
if (refTo) {
|
|
57
|
-
this.memoTypeDesc = refTo.
|
|
57
|
+
this.memoTypeDesc = refTo.typeDesc();
|
|
58
58
|
return this.memoTypeDesc;
|
|
59
59
|
}
|
|
60
60
|
return { dataType: 'error', expressionType: 'scalar', evalSpace: 'input' };
|
|
@@ -4,6 +4,6 @@ import { SpaceField } from '../types/space-field';
|
|
|
4
4
|
export declare class WildSpaceField extends SpaceField {
|
|
5
5
|
readonly wildText: string;
|
|
6
6
|
constructor(wildText: string);
|
|
7
|
-
|
|
7
|
+
typeDesc(): TypeDesc;
|
|
8
8
|
getQueryFieldDef(_fs: FieldSpace): QueryFieldDef;
|
|
9
9
|
}
|
|
@@ -274,7 +274,7 @@ class FieldDefinitionValue extends space_field_1.SpaceField {
|
|
|
274
274
|
// really know what type we have. However since we have the FieldSpace,
|
|
275
275
|
// we can compile the expression to find out, this might result in
|
|
276
276
|
// some expressions being compiled twice.
|
|
277
|
-
|
|
277
|
+
typeDesc() {
|
|
278
278
|
const typeFrom = this.qfd || this.fieldDef();
|
|
279
279
|
return this.fieldTypeFromFieldDef(typeFrom);
|
|
280
280
|
}
|
|
@@ -38,7 +38,7 @@ class Join extends malloy_element_1.MalloyElement {
|
|
|
38
38
|
this.extendNote = noteable_1.extendNoteMethod;
|
|
39
39
|
}
|
|
40
40
|
makeEntry(fs) {
|
|
41
|
-
fs.newEntry(this.name.refString, this, new join_space_field_1.JoinSpaceField(
|
|
41
|
+
fs.newEntry(this.name.refString, this, new join_space_field_1.JoinSpaceField(this));
|
|
42
42
|
}
|
|
43
43
|
getStructDefFromExpr() {
|
|
44
44
|
const source = this.sourceExpr.getSource();
|
|
@@ -41,7 +41,7 @@ class OrderBy extends malloy_element_1.MalloyElement {
|
|
|
41
41
|
return typeof this.field === 'number' ? this.field : this.field.refString;
|
|
42
42
|
}
|
|
43
43
|
getOrderBy(fs) {
|
|
44
|
-
var _a
|
|
44
|
+
var _a;
|
|
45
45
|
// TODO jump-to-definition now that we can lookup fields in the output space,
|
|
46
46
|
// we need to actually add the reference when we do so.
|
|
47
47
|
if (this.field instanceof field_space_1.FieldName && fs.isQueryFieldSpace()) {
|
|
@@ -50,10 +50,10 @@ class OrderBy extends malloy_element_1.MalloyElement {
|
|
|
50
50
|
if (entry.error) {
|
|
51
51
|
this.field.log(entry.error);
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
53
|
+
if (!entry.found || !entry.isOutputField) {
|
|
54
54
|
this.log(`Unknown field ${this.field.refString} in output space`);
|
|
55
55
|
}
|
|
56
|
-
if ((0, malloy_types_1.expressionIsAnalytic)((
|
|
56
|
+
if ((0, malloy_types_1.expressionIsAnalytic)((_a = entry.found) === null || _a === void 0 ? void 0 : _a.typeDesc().expressionType)) {
|
|
57
57
|
this.log(`Illegal order by of analytic field ${this.field.refString}`);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -100,7 +100,7 @@ class QOPDesc extends malloy_element_1.ListOf {
|
|
|
100
100
|
segment,
|
|
101
101
|
outputSpace: () =>
|
|
102
102
|
// TODO someday we'd like to get rid of the call to opOutputStruct here.
|
|
103
|
-
// If the `
|
|
103
|
+
// If the `build.resultFS` is correct, then we should be able to just use that
|
|
104
104
|
// in a more direct way.
|
|
105
105
|
new static_space_1.StaticSpace((0, struct_utils_1.opOutputStruct)(this, inputFS.structDef(), segment)),
|
|
106
106
|
};
|
|
@@ -68,7 +68,7 @@ class NamedRefinement extends Refinement {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
this.name.log(`named refinement \`${this.name.refString}\` must be a view, found a ${res.found.
|
|
71
|
+
this.name.log(`named refinement \`${this.name.refString}\` must be a view, found a ${res.found.typeDesc().dataType}`);
|
|
72
72
|
}
|
|
73
73
|
refine(inputFS, pipeline) {
|
|
74
74
|
if (pipeline.length === 1) {
|
|
@@ -39,7 +39,7 @@ class Top extends malloy_element_1.MalloyElement {
|
|
|
39
39
|
this.has({ by: by });
|
|
40
40
|
}
|
|
41
41
|
getBy(fs) {
|
|
42
|
-
var _a
|
|
42
|
+
var _a;
|
|
43
43
|
if (this.by) {
|
|
44
44
|
if (this.by instanceof field_space_1.FieldName) {
|
|
45
45
|
if (fs.isQueryFieldSpace()) {
|
|
@@ -50,10 +50,10 @@ class Top extends malloy_element_1.MalloyElement {
|
|
|
50
50
|
if (entry.error) {
|
|
51
51
|
this.by.log(entry.error);
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
53
|
+
if (!entry.found || !entry.isOutputField) {
|
|
54
54
|
this.by.log(`Unknown field ${this.by.refString} in output space`);
|
|
55
55
|
}
|
|
56
|
-
if ((0, malloy_types_1.expressionIsAnalytic)((
|
|
56
|
+
if ((0, malloy_types_1.expressionIsAnalytic)((_a = entry.found) === null || _a === void 0 ? void 0 : _a.typeDesc().expressionType)) {
|
|
57
57
|
this.by.log(`Illegal order by of analytic field ${this.by.refString}`);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -2,15 +2,8 @@ import { TypeDesc } from '../../../model';
|
|
|
2
2
|
import { DynamicSpace } from '../field-space/dynamic-space';
|
|
3
3
|
import { MalloyElement } from './malloy-element';
|
|
4
4
|
export declare abstract class SpaceEntry {
|
|
5
|
-
|
|
6
|
-
* Once upon a time this was called `typeDesc()` but now that is implemented here
|
|
7
|
-
* as a wrapper which knows about output spaces. Individual entries should describe
|
|
8
|
-
* themselves with describeType() and the typeDesc() here will call that.
|
|
9
|
-
*/
|
|
10
|
-
abstract describeType(): TypeDesc;
|
|
5
|
+
abstract typeDesc(): TypeDesc;
|
|
11
6
|
abstract refType: 'field' | 'parameter';
|
|
12
|
-
outputField: boolean;
|
|
13
|
-
typeDesc(): TypeDesc;
|
|
14
7
|
}
|
|
15
8
|
export interface MakeEntry {
|
|
16
9
|
makeEntry: (fs: DynamicSpace) => void;
|
|
@@ -24,19 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.canMakeEntry = exports.SpaceEntry = void 0;
|
|
26
26
|
class SpaceEntry {
|
|
27
|
-
constructor() {
|
|
28
|
-
this.outputField = false;
|
|
29
|
-
}
|
|
30
|
-
typeDesc() {
|
|
31
|
-
const type = this.describeType();
|
|
32
|
-
if (this.outputField) {
|
|
33
|
-
return {
|
|
34
|
-
...type,
|
|
35
|
-
evalSpace: type.evalSpace === 'constant' ? 'constant' : 'output',
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
return type;
|
|
39
|
-
}
|
|
40
27
|
}
|
|
41
28
|
exports.SpaceEntry = SpaceEntry;
|
|
42
29
|
function canMakeEntry(me) {
|
|
@@ -9,11 +9,11 @@ export declare class AbstractParameter extends SpaceParam {
|
|
|
9
9
|
readonly astParam: HasParameter;
|
|
10
10
|
constructor(astParam: HasParameter);
|
|
11
11
|
parameter(): Parameter;
|
|
12
|
-
|
|
12
|
+
typeDesc(): TypeDesc;
|
|
13
13
|
}
|
|
14
14
|
export declare class DefinedParameter extends SpaceParam {
|
|
15
15
|
readonly paramDef: Parameter;
|
|
16
16
|
constructor(paramDef: Parameter);
|
|
17
17
|
parameter(): Parameter;
|
|
18
|
-
|
|
18
|
+
typeDesc(): TypeDesc;
|
|
19
19
|
}
|
|
@@ -39,7 +39,7 @@ class AbstractParameter extends SpaceParam {
|
|
|
39
39
|
parameter() {
|
|
40
40
|
return this.astParam.parameter();
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
typeDesc() {
|
|
43
43
|
const type = this.astParam.type || 'error';
|
|
44
44
|
// TODO Not sure whether params are considered "input space". It seems like they
|
|
45
45
|
// could be input or constant, depending on usage.
|
|
@@ -55,7 +55,7 @@ class DefinedParameter extends SpaceParam {
|
|
|
55
55
|
parameter() {
|
|
56
56
|
return this.paramDef;
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
typeDesc() {
|
|
59
59
|
return {
|
|
60
60
|
dataType: this.paramDef.type,
|
|
61
61
|
expressionType: 'scalar',
|
|
@@ -65,12 +65,19 @@ describe('lenses', () => {
|
|
|
65
65
|
test('cannot override ordering', () => {
|
|
66
66
|
expect((0, test_translator_1.markSource) `
|
|
67
67
|
source: x is a extend {
|
|
68
|
-
view: d1 is { group_by: n1 is
|
|
69
|
-
view: d2 is { group_by: n2 is
|
|
68
|
+
view: d1 is { group_by: n1 is ai; order_by: n1 }
|
|
69
|
+
view: d2 is { group_by: n2 is 1; order_by: n2 }
|
|
70
70
|
}
|
|
71
71
|
run: x -> d1 + d2
|
|
72
72
|
`).translationToFailWith('refinement cannot override existing ordering');
|
|
73
73
|
});
|
|
74
|
+
test('weird issue with order by constant group by', () => {
|
|
75
|
+
expect((0, test_translator_1.markSource) `
|
|
76
|
+
source: x is a extend {
|
|
77
|
+
view: d1 is { group_by: n1 is 1; order_by: n1 }
|
|
78
|
+
}
|
|
79
|
+
`).toTranslate();
|
|
80
|
+
});
|
|
74
81
|
test('can add a limit late', () => {
|
|
75
82
|
expect((0, test_translator_1.markSource) `
|
|
76
83
|
source: x is a extend {
|
|
@@ -253,6 +260,14 @@ describe('lenses', () => {
|
|
|
253
260
|
run: x -> d + b
|
|
254
261
|
`).translationToFailWith('named refinement `b` must be a view, found a struct');
|
|
255
262
|
});
|
|
263
|
+
test('cannot reference field in LHS of refinement in group_by', () => {
|
|
264
|
+
expect((0, test_translator_1.markSource) `
|
|
265
|
+
source: x is a extend {
|
|
266
|
+
view: v is { group_by: i is 1 }
|
|
267
|
+
}
|
|
268
|
+
run: x -> v + { group_by: j is ${'i'} }
|
|
269
|
+
`).translationToFailWith("'i' is not defined");
|
|
270
|
+
});
|
|
256
271
|
test('cannot named-refine multi-stage query', () => {
|
|
257
272
|
expect((0, test_translator_1.markSource) `
|
|
258
273
|
source: x is a extend {
|
|
@@ -247,6 +247,50 @@ describe('source:', () => {
|
|
|
247
247
|
select: *
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
|
+
`).toTranslate();
|
|
251
|
+
});
|
|
252
|
+
test('chained explore-query with refinement two steps', () => {
|
|
253
|
+
expect(`
|
|
254
|
+
source: c is a extend {
|
|
255
|
+
view: base is {
|
|
256
|
+
group_by: astr
|
|
257
|
+
} + {
|
|
258
|
+
group_by: ai
|
|
259
|
+
}
|
|
260
|
+
view: chain2 is base -> {
|
|
261
|
+
top: 10; order_by: astr
|
|
262
|
+
select: *
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
`).toTranslate();
|
|
266
|
+
});
|
|
267
|
+
test('pipelined explore-query with refinement', () => {
|
|
268
|
+
expect(`
|
|
269
|
+
source: c is a extend {
|
|
270
|
+
view: base is {
|
|
271
|
+
group_by: astr
|
|
272
|
+
}
|
|
273
|
+
view: chain is base + {
|
|
274
|
+
group_by: ai
|
|
275
|
+
} -> {
|
|
276
|
+
top: 10; order_by: astr
|
|
277
|
+
select: *
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
`).toTranslate();
|
|
281
|
+
});
|
|
282
|
+
test.skip('pipelined explore-query with view chain', () => {
|
|
283
|
+
expect(`
|
|
284
|
+
source: c is a extend {
|
|
285
|
+
view: chain is {
|
|
286
|
+
group_by: astr
|
|
287
|
+
} + {
|
|
288
|
+
group_by: ai
|
|
289
|
+
} -> {
|
|
290
|
+
top: 10; order_by: astr
|
|
291
|
+
select: *
|
|
292
|
+
}
|
|
293
|
+
}
|
|
250
294
|
`).toTranslate();
|
|
251
295
|
});
|
|
252
296
|
test('multiple explore-query', () => {
|