@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.
Files changed (33) hide show
  1. package/dist/lang/ast/expressions/expr-id-reference.js +4 -3
  2. package/dist/lang/ast/field-space/column-space-field.d.ts +1 -1
  3. package/dist/lang/ast/field-space/column-space-field.js +1 -1
  4. package/dist/lang/ast/field-space/join-space-field.d.ts +1 -3
  5. package/dist/lang/ast/field-space/join-space-field.js +1 -2
  6. package/dist/lang/ast/field-space/query-space-field.d.ts +1 -1
  7. package/dist/lang/ast/field-space/query-space-field.js +1 -1
  8. package/dist/lang/ast/field-space/query-spaces.d.ts +0 -2
  9. package/dist/lang/ast/field-space/query-spaces.js +4 -9
  10. package/dist/lang/ast/field-space/reference-field.d.ts +1 -1
  11. package/dist/lang/ast/field-space/reference-field.js +2 -2
  12. package/dist/lang/ast/field-space/rename-space-field.d.ts +1 -1
  13. package/dist/lang/ast/field-space/rename-space-field.js +1 -1
  14. package/dist/lang/ast/field-space/static-space.js +1 -1
  15. package/dist/lang/ast/field-space/struct-space-field-base.d.ts +1 -1
  16. package/dist/lang/ast/field-space/struct-space-field-base.js +1 -1
  17. package/dist/lang/ast/field-space/wild-space-field.d.ts +1 -1
  18. package/dist/lang/ast/field-space/wild-space-field.js +1 -1
  19. package/dist/lang/ast/query-items/field-declaration.d.ts +1 -1
  20. package/dist/lang/ast/query-items/field-declaration.js +1 -1
  21. package/dist/lang/ast/query-properties/joins.js +1 -1
  22. package/dist/lang/ast/query-properties/ordering.js +3 -3
  23. package/dist/lang/ast/query-properties/qop-desc.js +1 -1
  24. package/dist/lang/ast/query-properties/refinements.js +1 -1
  25. package/dist/lang/ast/query-properties/top.js +3 -3
  26. package/dist/lang/ast/types/lookup-result.d.ts +1 -0
  27. package/dist/lang/ast/types/space-entry.d.ts +1 -8
  28. package/dist/lang/ast/types/space-entry.js +0 -13
  29. package/dist/lang/ast/types/space-param.d.ts +2 -2
  30. package/dist/lang/ast/types/space-param.js +2 -2
  31. package/dist/lang/test/lenses.spec.js +17 -2
  32. package/dist/lang/test/source.spec.js +44 -0
  33. 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
- if (def.found.typeDesc().evalSpace === 'output') {
43
+ const td = def.found.typeDesc();
44
+ if (def.isOutputField) {
44
45
  return {
45
- ...def.found.typeDesc(),
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'
@@ -4,5 +4,5 @@ export declare class ColumnSpaceField extends SpaceField {
4
4
  haveFieldDef: FieldDef;
5
5
  constructor(def: FieldTypeDef);
6
6
  fieldDef(): FieldDef;
7
- describeType(): TypeDesc;
7
+ typeDesc(): TypeDesc;
8
8
  }
@@ -32,7 +32,7 @@ class ColumnSpaceField extends space_field_1.SpaceField {
32
32
  fieldDef() {
33
33
  return this.haveFieldDef;
34
34
  }
35
- describeType() {
35
+ typeDesc() {
36
36
  return this.fieldTypeFromFieldDef(this.haveFieldDef);
37
37
  }
38
38
  }
@@ -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(intoFS: FieldSpace, join: Join);
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(intoFS, join) {
28
+ constructor(join) {
29
29
  super(join.structDef());
30
- this.intoFS = intoFS;
31
30
  this.join = join;
32
31
  }
33
32
  }
@@ -6,5 +6,5 @@ export declare abstract class QueryField extends SpaceField {
6
6
  constructor(inSpace: FieldSpace);
7
7
  abstract getQueryFieldDef(fs: FieldSpace): QueryFieldDef | undefined;
8
8
  abstract fieldDef(): FieldDef;
9
- describeType(): TypeDesc;
9
+ typeDesc(): TypeDesc;
10
10
  }
@@ -29,7 +29,7 @@ class QueryField extends space_field_1.SpaceField {
29
29
  super();
30
30
  this.inSpace = inSpace;
31
31
  }
32
- describeType() {
32
+ typeDesc() {
33
33
  return { dataType: 'turtle', expressionType: 'scalar', evalSpace: 'input' };
34
34
  }
35
35
  }
@@ -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. This is also true for
223
- // project statements, where we add "*" as a field and also all the individuala
224
- // fields, but the individual fields don't have field defs.
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
- describeType(): TypeDesc;
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
- describeType() {
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.describeType();
57
+ this.memoTypeDesc = refTo.typeDesc();
58
58
  return this.memoTypeDesc;
59
59
  }
60
60
  return { dataType: 'error', expressionType: 'scalar', evalSpace: 'input' };
@@ -6,5 +6,5 @@ export declare class RenameSpaceField extends SpaceField {
6
6
  private readonly location;
7
7
  constructor(otherField: SpaceField, newName: string, location: DocumentLocation);
8
8
  fieldDef(): FieldDef | undefined;
9
- describeType(): TypeDesc;
9
+ typeDesc(): TypeDesc;
10
10
  }
@@ -42,7 +42,7 @@ class RenameSpaceField extends space_field_1.SpaceField {
42
42
  location: this.location,
43
43
  };
44
44
  }
45
- describeType() {
45
+ typeDesc() {
46
46
  return this.otherField.typeDesc();
47
47
  }
48
48
  }
@@ -158,7 +158,7 @@ class StaticSpace {
158
158
  found: undefined,
159
159
  };
160
160
  }
161
- return { found, error: undefined, relationship };
161
+ return { found, error: undefined, relationship, isOutputField: false };
162
162
  }
163
163
  isQueryFieldSpace() {
164
164
  return false;
@@ -7,5 +7,5 @@ export declare abstract class StructSpaceFieldBase extends SpaceField {
7
7
  abstract get fieldSpace(): FieldSpace;
8
8
  get structRelationship(): StructRelationship;
9
9
  fieldDef(): FieldDef;
10
- describeType(): TypeDesc;
10
+ typeDesc(): TypeDesc;
11
11
  }
@@ -35,7 +35,7 @@ class StructSpaceFieldBase extends space_field_1.SpaceField {
35
35
  fieldDef() {
36
36
  return this.sourceDef;
37
37
  }
38
- describeType() {
38
+ typeDesc() {
39
39
  return { dataType: 'struct', expressionType: 'scalar', evalSpace: 'input' };
40
40
  }
41
41
  }
@@ -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
- describeType(): TypeDesc;
7
+ typeDesc(): TypeDesc;
8
8
  getQueryFieldDef(_fs: FieldSpace): QueryFieldDef;
9
9
  }
@@ -29,7 +29,7 @@ class WildSpaceField extends space_field_1.SpaceField {
29
29
  super();
30
30
  this.wildText = wildText;
31
31
  }
32
- describeType() {
32
+ typeDesc() {
33
33
  throw new Error('should never ask a wild field for its type');
34
34
  }
35
35
  getQueryFieldDef(_fs) {
@@ -82,5 +82,5 @@ export declare class FieldDefinitionValue extends SpaceField {
82
82
  fieldDef(): FieldDef;
83
83
  private qfd?;
84
84
  getQueryFieldDef(fs: FieldSpace): QueryFieldDef;
85
- describeType(): TypeDesc;
85
+ typeDesc(): TypeDesc;
86
86
  }
@@ -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
- describeType() {
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(fs, this));
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, _b;
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 (((_a = entry.found) === null || _a === void 0 ? void 0 : _a.typeDesc().evalSpace) === 'input') {
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)((_b = entry.found) === null || _b === void 0 ? void 0 : _b.typeDesc().expressionType)) {
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 `qex.resultFS` is correct, then we should be able to just use that
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.describeType().dataType}`);
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, _b;
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 (((_a = entry.found) === null || _a === void 0 ? void 0 : _a.typeDesc().evalSpace) === 'input') {
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)((_b = entry.found) === null || _b === void 0 ? void 0 : _b.typeDesc().expressionType)) {
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
  }
@@ -7,6 +7,7 @@ export interface LookupFound {
7
7
  structRelationship: StructRelationship;
8
8
  }[];
9
9
  error: undefined;
10
+ isOutputField: boolean;
10
11
  }
11
12
  export interface LookupError {
12
13
  error: string;
@@ -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
- describeType(): TypeDesc;
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
- describeType(): TypeDesc;
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
- describeType() {
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
- describeType() {
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 1; order_by: n1 }
69
- view: d2 is { group_by: n2 is 2; order_by: n2 }
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', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.101-dev231109201517",
3
+ "version": "0.0.101-dev231110210501",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",