@malloydata/malloy 0.0.101-dev231109201517 → 0.0.101-dev231110211921
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/parse-malloy.d.ts +1 -1
- package/dist/lang/parse-malloy.js +12 -10
- package/dist/lang/test/imports.spec.js +10 -0
- package/dist/lang/test/lenses.spec.js +17 -2
- package/dist/lang/test/source.spec.js +44 -0
- package/dist/lang/translate-response.d.ts +1 -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',
|
|
@@ -112,6 +112,7 @@ export declare abstract class MalloyTranslation {
|
|
|
112
112
|
readonly references: ReferenceList;
|
|
113
113
|
constructor(sourceURL: string, importBaseURL?: string | null, grammarRule?: string);
|
|
114
114
|
addChild(url: string): void;
|
|
115
|
+
getDependencies(): string[];
|
|
115
116
|
addReference(reference: DocumentReference): void;
|
|
116
117
|
referenceAt(position: DocumentPosition): DocumentReference | undefined;
|
|
117
118
|
/**
|
|
@@ -134,7 +135,6 @@ export declare abstract class MalloyTranslation {
|
|
|
134
135
|
private finalAnswer?;
|
|
135
136
|
translate(extendingModel?: ModelDef): TranslateResponse;
|
|
136
137
|
importAt(position: DocumentPosition): ImportLocation | undefined;
|
|
137
|
-
private buildImports;
|
|
138
138
|
metadata(): MetadataResponse;
|
|
139
139
|
completions(position: {
|
|
140
140
|
line: number;
|
|
@@ -217,6 +217,10 @@ class ImportsAndTablesStep {
|
|
|
217
217
|
try {
|
|
218
218
|
const ref = decodeURI(new URL(relativeRef, that.importBaseURL || that.sourceURL).toString());
|
|
219
219
|
that.addChild(ref);
|
|
220
|
+
that.imports.push({
|
|
221
|
+
importURL: ref,
|
|
222
|
+
location: { url: that.sourceURL, range: firstRef },
|
|
223
|
+
});
|
|
220
224
|
that.root.importZone.reference(ref, {
|
|
221
225
|
url: that.sourceURL,
|
|
222
226
|
range: firstRef,
|
|
@@ -507,6 +511,7 @@ class TranslateStep {
|
|
|
507
511
|
queryList: that.queryList,
|
|
508
512
|
sqlBlocks: that.sqlBlocks,
|
|
509
513
|
},
|
|
514
|
+
fromSources: that.getDependencies(),
|
|
510
515
|
...that.problemResponse(),
|
|
511
516
|
final: true,
|
|
512
517
|
};
|
|
@@ -550,6 +555,13 @@ class MalloyTranslation {
|
|
|
550
555
|
this.childTranslators.set(url, new MalloyChildTranslator(url, this.root));
|
|
551
556
|
}
|
|
552
557
|
}
|
|
558
|
+
getDependencies() {
|
|
559
|
+
const dependencies = [this.sourceURL];
|
|
560
|
+
for (const [_childURL, child] of this.childTranslators) {
|
|
561
|
+
dependencies.push(...child.getDependencies());
|
|
562
|
+
}
|
|
563
|
+
return dependencies;
|
|
564
|
+
}
|
|
553
565
|
addReference(reference) {
|
|
554
566
|
this.references.add(reference);
|
|
555
567
|
}
|
|
@@ -671,7 +683,6 @@ class MalloyTranslation {
|
|
|
671
683
|
const attempt = this.translateStep.step(this, extendingModel);
|
|
672
684
|
if (attempt.final) {
|
|
673
685
|
this.finalAnswer = attempt;
|
|
674
|
-
this.buildImports();
|
|
675
686
|
}
|
|
676
687
|
return attempt;
|
|
677
688
|
}
|
|
@@ -686,15 +697,6 @@ class MalloyTranslation {
|
|
|
686
697
|
}
|
|
687
698
|
return undefined;
|
|
688
699
|
}
|
|
689
|
-
buildImports() {
|
|
690
|
-
for (const [key, value] of Object.entries(this.root.importZone.location)) {
|
|
691
|
-
// Ignore any import in another file
|
|
692
|
-
if (value.url !== this.sourceURL) {
|
|
693
|
-
continue;
|
|
694
|
-
}
|
|
695
|
-
this.imports.push({ importURL: key, location: value });
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
700
|
metadata() {
|
|
699
701
|
return this.metadataStep.step(this);
|
|
700
702
|
}
|
|
@@ -120,6 +120,16 @@ source: botProjQSrc is botProjQ
|
|
|
120
120
|
const xr = docParse.unresolved();
|
|
121
121
|
expect(docParse).toParse();
|
|
122
122
|
expect(xr).toEqual({ urls: ['internal://test/langtests/grandChild'] });
|
|
123
|
+
docParse.update({
|
|
124
|
+
urls: { 'internal://test/langtests/grandChild': '// empty file' },
|
|
125
|
+
});
|
|
126
|
+
expect(docParse).toTranslate();
|
|
127
|
+
const sources = docParse.translate().fromSources;
|
|
128
|
+
expect(sources).toEqual([
|
|
129
|
+
'internal://test/langtests/root.malloy',
|
|
130
|
+
'internal://test/langtests/child',
|
|
131
|
+
'internal://test/langtests/grandChild',
|
|
132
|
+
]);
|
|
123
133
|
});
|
|
124
134
|
test('relative imports', () => {
|
|
125
135
|
const docParse = new test_translator_1.TestTranslator('import "../parent.malloy"');
|
|
@@ -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', () => {
|