@malloydata/malloy 0.0.119-dev240123183113 → 0.0.119-dev240124170348

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 (52) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +1 -3
  3. package/dist/lang/ast/error-factory.js +3 -3
  4. package/dist/lang/ast/expressions/expr-aggregate-function.d.ts +6 -4
  5. package/dist/lang/ast/expressions/expr-aggregate-function.js +24 -13
  6. package/dist/lang/ast/expressions/expr-count.js +1 -1
  7. package/dist/lang/ast/expressions/expr-func.js +4 -4
  8. package/dist/lang/ast/expressions/expr-id-reference.js +2 -2
  9. package/dist/lang/ast/field-space/dynamic-space.js +1 -1
  10. package/dist/lang/ast/field-space/index-field-space.d.ts +5 -3
  11. package/dist/lang/ast/field-space/index-field-space.js +85 -16
  12. package/dist/lang/ast/field-space/query-input-space.d.ts +3 -3
  13. package/dist/lang/ast/field-space/query-spaces.d.ts +15 -12
  14. package/dist/lang/ast/field-space/query-spaces.js +60 -57
  15. package/dist/lang/ast/field-space/reference-field.d.ts +0 -5
  16. package/dist/lang/ast/field-space/reference-field.js +16 -46
  17. package/dist/lang/ast/query-builders/index-builder.d.ts +2 -2
  18. package/dist/lang/ast/query-builders/partial-builder.js +28 -1
  19. package/dist/lang/ast/query-builders/project-builder.d.ts +8 -4
  20. package/dist/lang/ast/query-builders/project-builder.js +5 -6
  21. package/dist/lang/ast/query-builders/reduce-builder.d.ts +13 -8
  22. package/dist/lang/ast/query-builders/reduce-builder.js +12 -9
  23. package/dist/lang/ast/query-items/field-declaration.d.ts +1 -1
  24. package/dist/lang/ast/query-items/field-references.d.ts +5 -1
  25. package/dist/lang/ast/query-items/field-references.js +17 -1
  26. package/dist/lang/ast/query-properties/qop-desc.d.ts +2 -2
  27. package/dist/lang/ast/source-properties/joins.js +1 -1
  28. package/dist/lang/ast/types/field-space.d.ts +2 -2
  29. package/dist/lang/ast/types/query-builder.d.ts +2 -2
  30. package/dist/lang/ast/view-elements/qop-desc-view.d.ts +3 -3
  31. package/dist/lang/ast/view-elements/reference-view.d.ts +3 -3
  32. package/dist/lang/ast/view-elements/reference-view.js +1 -1
  33. package/dist/lang/ast/view-elements/refine-utils.js +20 -18
  34. package/dist/lang/ast/view-elements/view-arrow.d.ts +2 -2
  35. package/dist/lang/ast/view-elements/view-refine.d.ts +3 -3
  36. package/dist/lang/ast/view-elements/view.d.ts +4 -4
  37. package/dist/lang/field-utils.d.ts +3 -3
  38. package/dist/lang/field-utils.js +9 -8
  39. package/dist/lang/test/annotation.spec.js +26 -27
  40. package/dist/lang/test/expressions.spec.js +43 -40
  41. package/dist/lang/test/field-symbols.spec.js +4 -4
  42. package/dist/lang/test/locations.spec.js +13 -6
  43. package/dist/lang/test/query.spec.js +44 -56
  44. package/dist/lang/test/test-translator.d.ts +3 -2
  45. package/dist/lang/test/test-translator.js +30 -24
  46. package/dist/malloy.js +1 -1
  47. package/dist/model/malloy_query.d.ts +14 -36
  48. package/dist/model/malloy_query.js +145 -312
  49. package/dist/model/malloy_types.d.ts +18 -23
  50. package/dist/model/malloy_types.js +2 -15
  51. package/dist/tags.js +19 -4
  52. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { DuckDBDialect, StandardSQLDialect, PostgresDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, sqlFragment, param, spread, Dialect, FUNCTIONS, } from './dialect';
2
2
  export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, } from './dialect';
3
- export type { QueryDataRow, Fragment, StructDef, StructRelationship, NamedStructDefs, MalloyQueryData, AtomicFieldType as AtomicFieldTypeInner, DateUnit, ExtractUnit, TimestampUnit, TimeFieldType, QueryData, QueryValue, FieldTypeDef, Expr, DialectFragment, TimeValue, FilterExpression, SQLBlock, FieldAtomicDef, FieldDef, FilteredAliasedName, PipeSegment, QueryFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FieldValueType, ExpressionTypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, TypecastFragment, Annotation, FieldAtomicTypeDef, SQLBlockStructDef, } from './model';
4
- export { Segment, isFilteredAliasedName, isSamplingEnable, isSamplingPercent, isSamplingRows, mkExpr, expressionIsCalculation, indent, } from './model';
3
+ export type { QueryDataRow, Fragment, StructDef, StructRelationship, NamedStructDefs, MalloyQueryData, AtomicFieldType as AtomicFieldTypeInner, DateUnit, ExtractUnit, TimestampUnit, TimeFieldType, QueryData, QueryValue, FieldTypeDef, Expr, DialectFragment, TimeValue, FilterExpression, SQLBlock, FieldAtomicDef, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FieldValueType, ExpressionTypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, TypecastFragment, Annotation, FieldAtomicTypeDef, SQLBlockStructDef, } from './model';
4
+ export { Segment, isSamplingEnable, isSamplingPercent, isSamplingRows, mkExpr, expressionIsCalculation, indent, } from './model';
5
5
  export { HighlightType, MalloyTranslator, } from './lang';
6
6
  export type { LogMessage, TranslateResponse } from './lang';
7
7
  export { Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, } from './malloy';
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toAsyncGenerator = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.MalloyTranslator = exports.HighlightType = exports.indent = exports.expressionIsCalculation = exports.mkExpr = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isFilteredAliasedName = exports.Segment = exports.FUNCTIONS = exports.Dialect = exports.spread = exports.param = exports.sqlFragment = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.PostgresDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
4
- exports.Tag = void 0;
3
+ exports.Tag = exports.toAsyncGenerator = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.MalloyTranslator = exports.HighlightType = exports.indent = exports.expressionIsCalculation = exports.mkExpr = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.Segment = exports.FUNCTIONS = exports.Dialect = exports.spread = exports.param = exports.sqlFragment = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.PostgresDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
5
4
  /*
6
5
  * Copyright 2023 Google LLC
7
6
  *
@@ -46,7 +45,6 @@ Object.defineProperty(exports, "FUNCTIONS", { enumerable: true, get: function ()
46
45
  var model_1 = require("./model");
47
46
  // Used in Composer Demo
48
47
  Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
49
- Object.defineProperty(exports, "isFilteredAliasedName", { enumerable: true, get: function () { return model_1.isFilteredAliasedName; } });
50
48
  Object.defineProperty(exports, "isSamplingEnable", { enumerable: true, get: function () { return model_1.isSamplingEnable; } });
51
49
  Object.defineProperty(exports, "isSamplingPercent", { enumerable: true, get: function () { return model_1.isSamplingPercent; } });
52
50
  Object.defineProperty(exports, "isSamplingRows", { enumerable: true, get: function () { return model_1.isSamplingRows; } });
@@ -51,13 +51,13 @@ class ErrorFactory {
51
51
  };
52
52
  }
53
53
  static get reduceSegment() {
54
- return { type: 'reduce', fields: [] };
54
+ return { type: 'reduce', queryFields: [] };
55
55
  }
56
56
  static get projectSegment() {
57
- return { type: 'project', fields: [] };
57
+ return { type: 'project', queryFields: [] };
58
58
  }
59
59
  static get indexSegment() {
60
- return { type: 'index', fields: [] };
60
+ return { type: 'index', indexFields: [] };
61
61
  }
62
62
  }
63
63
  exports.ErrorFactory = ErrorFactory;
@@ -3,6 +3,10 @@ import { FieldReference } from '../query-items/field-references';
3
3
  import { ExprValue } from '../types/expr-value';
4
4
  import { ExpressionDef } from '../types/expression-def';
5
5
  import { FieldSpace } from '../types/field-space';
6
+ interface JoinPathElement {
7
+ name: string;
8
+ structRelationship: StructRelationship;
9
+ }
6
10
  export declare abstract class ExprAggregateFunction extends ExpressionDef {
7
11
  readonly func: AggregateFunctionType;
8
12
  elementType: string;
@@ -14,8 +18,6 @@ export declare abstract class ExprAggregateFunction extends ExpressionDef {
14
18
  returns(_forExpression: ExprValue): FieldValueType;
15
19
  getExpression(fs: FieldSpace): ExprValue;
16
20
  isSymmetricFunction(): boolean;
17
- getJoinUsage(fs: FieldSpace): {
18
- name: string;
19
- structRelationship: StructRelationship;
20
- }[][];
21
+ getJoinUsage(fs: FieldSpace): JoinPathElement[][];
21
22
  }
23
+ export {};
@@ -55,7 +55,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
55
55
  const inputFS = fs.isQueryFieldSpace() ? fs.inputSpace() : fs;
56
56
  let expr = this.expr;
57
57
  let exprVal = (_a = this.expr) === null || _a === void 0 ? void 0 : _a.getExpression(inputFS);
58
- let structPath = (_b = this.source) === null || _b === void 0 ? void 0 : _b.refString;
58
+ let structPath = (_b = this.source) === null || _b === void 0 ? void 0 : _b.path;
59
59
  let sourceRelationship = [];
60
60
  if (this.source) {
61
61
  const result = this.source.getField(inputFS);
@@ -76,21 +76,20 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
76
76
  }
77
77
  : {
78
78
  type: 'field',
79
- path: this.source.refString,
79
+ path: this.source.path,
80
80
  },
81
81
  ],
82
82
  evalSpace: footType.evalSpace,
83
83
  };
84
- structPath = this.source.sourceString;
84
+ structPath = this.source.path;
85
85
  // Here we handle a special case where you write `foo.agg()` and `foo` is a
86
86
  // dimension which uses only one distinct join path; in this case, we set the
87
87
  // locality to be that join path
88
88
  const joinUsage = this.getJoinUsage(inputFS);
89
- const allUsagePaths = joinUsage.map(x => x.map(y => y.name).join('.'));
90
- const allUsagesSame = allUsagePaths.length > 0 &&
91
- allUsagePaths.slice(1).every(x => x === allUsagePaths[0]);
89
+ const allUsagesSame = joinUsage.length === 1 ||
90
+ joinUsage.slice(1).every(p => joinPathEq(p, joinUsage[0]));
92
91
  if (allUsagesSame) {
93
- structPath = allUsagePaths[0];
92
+ structPath = joinUsage[0].map(p => p.name);
94
93
  sourceRelationship = joinUsage[0];
95
94
  }
96
95
  }
@@ -144,7 +143,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
144
143
  function: this.func,
145
144
  e: exprVal.value,
146
145
  };
147
- if (structPath) {
146
+ if (structPath && structPath.length > 0) {
148
147
  f.structPath = structPath;
149
148
  }
150
149
  return {
@@ -164,7 +163,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
164
163
  if (this.source) {
165
164
  const lookup = this.source.getField(fs);
166
165
  if (lookup.found) {
167
- const sfd = [{ type: 'field', path: this.source.refString }];
166
+ const sfd = [{ type: 'field', path: this.source.path }];
168
167
  result.push(...getJoinUsage(fs, sfd));
169
168
  }
170
169
  }
@@ -176,18 +175,30 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
176
175
  }
177
176
  }
178
177
  exports.ExprAggregateFunction = ExprAggregateFunction;
178
+ function joinPathEq(a1, a2) {
179
+ let len = a1.length;
180
+ if (len !== a2.length) {
181
+ return false;
182
+ }
183
+ while (len > 0) {
184
+ len -= 1;
185
+ if (a1[len].name !== a2[len].name) {
186
+ return false;
187
+ }
188
+ }
189
+ return true;
190
+ }
179
191
  function getJoinUsage(fs, expr) {
180
192
  const result = [];
181
193
  const lookup = (fs, path) => {
182
- const parts = path.split('.');
183
- const head = parts[0];
184
- const rest = parts.slice(1);
194
+ const head = path[0];
195
+ const rest = path.slice(1);
185
196
  const def = fs.entry(head);
186
197
  if (def === undefined) {
187
198
  throw new Error(`Invalid field lookup ${head}`);
188
199
  }
189
200
  if (def instanceof static_space_1.StructSpaceField && rest.length > 0) {
190
- const restDef = lookup(def.fieldSpace, rest.join('.'));
201
+ const restDef = lookup(def.fieldSpace, rest);
191
202
  return {
192
203
  ...restDef,
193
204
  relationship: [
@@ -44,7 +44,7 @@ class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
44
44
  e: [],
45
45
  };
46
46
  if (this.source) {
47
- ret.structPath = this.source.refString;
47
+ ret.structPath = this.source.path;
48
48
  }
49
49
  return {
50
50
  dataType: 'number',
@@ -82,7 +82,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
82
82
  // Find the 'implicit argument' for aggregate functions called like `some_join.some_field.agg(...args)`
83
83
  // where the full arg list is `(some_field, ...args)`.
84
84
  let implicitExpr = undefined;
85
- let structPath = (_d = this.source) === null || _d === void 0 ? void 0 : _d.refString;
85
+ let structPath = (_d = this.source) === null || _d === void 0 ? void 0 : _d.path;
86
86
  if (this.source) {
87
87
  const sourceFoot = this.source.getField(fs).found;
88
88
  if (sourceFoot) {
@@ -91,10 +91,10 @@ class ExprFunc extends expression_def_1.ExpressionDef {
91
91
  implicitExpr = {
92
92
  dataType: footType.dataType,
93
93
  expressionType: footType.expressionType,
94
- value: [{ type: 'field', path: this.source.refString }],
94
+ value: [{ type: 'field', path: this.source.path }],
95
95
  evalSpace: footType.evalSpace,
96
96
  };
97
- structPath = this.source.sourceString;
97
+ structPath = this.source.path.slice(0, -1);
98
98
  }
99
99
  else {
100
100
  if (!(sourceFoot instanceof struct_space_field_base_1.StructSpaceFieldBase)) {
@@ -209,7 +209,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
209
209
  ? part.value
210
210
  : part.name === 'TABLE'
211
211
  ? { type: 'source-reference' }
212
- : { type: 'field-reference', path: part.name }),
212
+ : { type: 'field', path: [part.name] }),
213
213
  },
214
214
  ];
215
215
  }
@@ -48,7 +48,7 @@ class ExprIdReference extends expression_def_1.ExpressionDef {
48
48
  value: [{ type: 'outputField', name: this.refString }],
49
49
  };
50
50
  }
51
- const value = [{ type: def.found.refType, path: this.refString }];
51
+ const value = [{ type: def.found.refType, path: this.fieldReference.path }];
52
52
  // We think that aggregates are more 'output' like, but maybe we will reconsider that...
53
53
  const evalSpace = (0, malloy_types_1.expressionIsAggregate)(td.expressionType)
54
54
  ? 'output'
@@ -73,7 +73,7 @@ class ExprIdReference extends expression_def_1.ExpressionDef {
73
73
  {
74
74
  type: 'apply',
75
75
  value: lval.value,
76
- to: [{ type: 'parameter', path: this.refString }],
76
+ to: [{ type: 'parameter', path: this.fieldReference.path }],
77
77
  },
78
78
  ],
79
79
  };
@@ -68,7 +68,7 @@ class DynamicSpace extends static_space_1.StaticSpace {
68
68
  this.setEntry(newName, entry);
69
69
  }
70
70
  addFieldDef(fd) {
71
- this.setEntry((0, field_utils_1.nameOf)(fd), this.defToSpaceField(fd));
71
+ this.setEntry((0, field_utils_1.nameFromDef)(fd), this.defToSpaceField(fd));
72
72
  }
73
73
  setTimezone(tz) {
74
74
  this.newTimezone = tz;
@@ -1,9 +1,11 @@
1
1
  import { IndexSegment, PipeSegment } from '../../../model/malloy_types';
2
+ import { WildcardFieldReference } from '../query-items/field-references';
2
3
  import { MalloyElement } from '../types/malloy-element';
3
- import { QuerySpace } from './query-spaces';
4
- export declare class IndexFieldSpace extends QuerySpace {
4
+ import { QueryOperationSpace } from './query-spaces';
5
+ export declare class IndexFieldSpace extends QueryOperationSpace {
5
6
  readonly segmentType = "index";
6
- fieldList: Set<string>;
7
7
  pushFields(...defs: MalloyElement[]): void;
8
8
  getPipeSegment(refineIndex?: PipeSegment): IndexSegment;
9
+ addRefineFromFields(_refineThis: never): void;
10
+ protected addWild(wild: WildcardFieldReference): void;
9
11
  }
@@ -23,24 +23,24 @@
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.IndexFieldSpace = void 0;
26
+ const malloy_types_1 = require("../../../model/malloy_types");
26
27
  const field_references_1 = require("../query-items/field-references");
28
+ const space_field_1 = require("../types/space-field");
27
29
  const query_spaces_1 = require("./query-spaces");
28
- class IndexFieldSpace extends query_spaces_1.QuerySpace {
30
+ const reference_field_1 = require("./reference-field");
31
+ const static_space_1 = require("./static-space");
32
+ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
29
33
  constructor() {
30
34
  super(...arguments);
31
35
  this.segmentType = 'index';
32
- this.fieldList = new Set();
33
36
  }
34
37
  pushFields(...defs) {
35
38
  for (const indexField of defs) {
36
39
  if (indexField instanceof field_references_1.FieldReference) {
37
- if (indexField.getField(this.inputSpace()).found) {
38
- this.fieldList.add(indexField.refString);
39
- }
40
- // mtoy TODO else error ???
40
+ super.pushFields(indexField);
41
41
  }
42
42
  else if (indexField instanceof field_references_1.WildcardFieldReference) {
43
- this.fieldList.add(indexField.refString);
43
+ this.addWild(indexField);
44
44
  }
45
45
  else {
46
46
  indexField.log('Internal error, not expected in index query');
@@ -48,18 +48,87 @@ class IndexFieldSpace extends query_spaces_1.QuerySpace {
48
48
  }
49
49
  }
50
50
  getPipeSegment(refineIndex) {
51
- if (refineIndex && refineIndex.fields) {
52
- for (const exists of refineIndex.fields) {
53
- if (typeof exists === 'string') {
54
- this.fieldList.add(exists);
51
+ if (refineIndex) {
52
+ this.log('index query operations cannot be refined');
53
+ return { type: 'index', indexFields: [] };
54
+ }
55
+ const indexFields = [];
56
+ for (const [name, field] of this.entries()) {
57
+ if (field instanceof space_field_1.SpaceField) {
58
+ const wildPath = this.expandedWild[name];
59
+ if (wildPath) {
60
+ indexFields.push({ type: 'fieldref', path: wildPath });
61
+ continue;
62
+ }
63
+ if (field instanceof reference_field_1.ReferenceField) {
64
+ // attempt to cause a type check
65
+ const fieldRef = field.fieldRef;
66
+ const check = fieldRef.getField(this.exprSpace);
67
+ if (check.error) {
68
+ fieldRef.log(check.error);
69
+ }
70
+ else {
71
+ indexFields.push(fieldRef.refToField);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ return { type: 'index', indexFields };
77
+ }
78
+ addRefineFromFields(_refineThis) { }
79
+ addWild(wild) {
80
+ var _a;
81
+ let current = this.exprSpace;
82
+ const joinPath = [];
83
+ if (wild.joinPath) {
84
+ // walk path to determine namespace for *
85
+ for (const pathPart of wild.joinPath.list) {
86
+ const part = pathPart.refString;
87
+ joinPath.push(part);
88
+ const ent = current.entry(part);
89
+ if (ent) {
90
+ if (ent instanceof static_space_1.StructSpaceField) {
91
+ current = ent.fieldSpace;
92
+ }
93
+ else {
94
+ pathPart.log(`Field '${part}' does not contain rows and cannot be expanded with '*'`);
95
+ return;
96
+ }
97
+ }
98
+ else {
99
+ pathPart.log(`No such field as '${part}'`);
100
+ return;
55
101
  }
56
102
  }
57
103
  }
58
- this.isComplete();
59
- return {
60
- type: 'index',
61
- fields: Array.from(this.fieldList.values()),
62
- };
104
+ const dialect = this.dialectObj();
105
+ const expandEntries = [];
106
+ for (const [name, entry] of current.entries()) {
107
+ if (wild.except.has(name)) {
108
+ continue;
109
+ }
110
+ const indexName = field_references_1.IndexFieldReference.indexOutputName([
111
+ ...joinPath,
112
+ name,
113
+ ]);
114
+ if (this.entry(indexName)) {
115
+ const conflict = (_a = this.expandedWild[indexName]) === null || _a === void 0 ? void 0 : _a.join('.');
116
+ wild.log(`Cannot expand '${name}' in '${wild.refString}' because a field with that name already exists${conflict ? ` (conflicts with ${conflict})` : ''}`);
117
+ }
118
+ else {
119
+ const eType = entry.typeDesc();
120
+ if ((0, malloy_types_1.isAtomicFieldType)(eType.dataType) &&
121
+ (0, malloy_types_1.expressionIsScalar)(eType.expressionType) &&
122
+ (dialect === undefined || !dialect.ignoreInProject(name))) {
123
+ expandEntries.push({ name: indexName, entry });
124
+ this.expandedWild[indexName] = joinPath.concat(name);
125
+ }
126
+ }
127
+ }
128
+ // There were tests which expected these to be sorted, and that seems reasonable
129
+ for (const x of expandEntries.sort((a, b) => a.name.localeCompare(b.name))) {
130
+ this.setEntry(x.name, x.entry);
131
+ }
63
132
  }
64
133
  }
65
134
  exports.IndexFieldSpace = IndexFieldSpace;
@@ -9,7 +9,7 @@ import { AtomicFieldDeclaration } from '../query-items/field-declaration';
9
9
  import { Join } from '../source-properties/joins';
10
10
  import { SourceSpec } from '../space-seed';
11
11
  import { QueryFieldSpace } from '../types/field-space';
12
- import { QuerySpace } from './query-spaces';
12
+ import { QueryOperationSpace } from './query-spaces';
13
13
  import { RefinedSpace } from './refined-space';
14
14
  export declare class QueryInputSpace extends RefinedSpace implements QueryFieldSpace {
15
15
  private queryOutput;
@@ -20,9 +20,9 @@ export declare class QueryInputSpace extends RefinedSpace implements QueryFieldS
20
20
  * @param input The source which might be extended
21
21
  * @param queryOutput MUST BE A QuerySpace
22
22
  */
23
- constructor(input: SourceSpec, queryOutput: QuerySpace);
23
+ constructor(input: SourceSpec, queryOutput: QueryOperationSpace);
24
24
  extendSource(extendField: Join | AtomicFieldDeclaration): void;
25
25
  isQueryFieldSpace(): boolean;
26
- outputSpace(): QuerySpace;
26
+ outputSpace(): QueryOperationSpace;
27
27
  inputSpace(): this;
28
28
  }
@@ -6,31 +6,34 @@ import { RefinedSpace } from './refined-space';
6
6
  import { LookupResult } from '../types/lookup-result';
7
7
  import { QueryInputSpace } from './query-input-space';
8
8
  /**
9
- * The output space of a query operation, it is not named "QueryOutputSpace"
10
- * because this is the namespace of the Query. This is the one which is constructed
11
- * with the query. The QueryInputSpace is created and paired when a
12
- * QuerySpace is created.
9
+ * The output space of a query operation. It is not named "QueryOutputSpace"
10
+ * because this is the namespace of the Query which is a layer of an output and
11
+ * an input space. It constructed with the query operation. A QueryInputSpace is
12
+ * created and paired when a QueryOperationSpace is created.
13
13
  */
14
- export declare abstract class QuerySpace extends RefinedSpace implements QueryFieldSpace {
14
+ export declare abstract class QueryOperationSpace extends RefinedSpace implements QueryFieldSpace {
15
15
  readonly queryInputSpace: FieldSpace;
16
- readonly nestParent: QuerySpace | undefined;
16
+ readonly nestParent: QueryOperationSpace | undefined;
17
17
  readonly astEl: MalloyElement;
18
- private exprSpace;
18
+ protected exprSpace: QueryInputSpace;
19
19
  abstract readonly segmentType: 'reduce' | 'project' | 'index';
20
20
  expandedWild: Record<string, string[]>;
21
- constructor(queryInputSpace: FieldSpace, refineThis: model.PipeSegment | undefined, nestParent: QuerySpace | undefined, astEl: MalloyElement);
22
- private addRefineFromFields;
21
+ constructor(queryInputSpace: FieldSpace, refineThis: model.PipeSegment | undefined, nestParent: QueryOperationSpace | undefined, astEl: MalloyElement);
22
+ abstract addRefineFromFields(refineThis: model.PipeSegment): void;
23
23
  log(s: string): void;
24
- pushFields(...defs: MalloyElement[]): void;
24
+ inputSpace(): QueryInputSpace;
25
+ outputSpace(): QueryOperationSpace;
25
26
  protected addWild(wild: WildcardFieldReference): void;
27
+ }
28
+ export declare abstract class QuerySpace extends QueryOperationSpace {
29
+ addRefineFromFields(refineThis: model.PipeSegment): void;
30
+ pushFields(...defs: MalloyElement[]): void;
26
31
  canContain(_typeDesc: model.TypeDesc): boolean;
27
32
  protected queryFieldDefs(): model.QueryFieldDef[];
28
33
  getQuerySegment(rf: model.QuerySegment | undefined): model.QuerySegment;
29
34
  getPipeSegment(refineFrom: model.QuerySegment | undefined): model.PipeSegment;
30
35
  lookup(path: FieldName[]): LookupResult;
31
36
  isQueryFieldSpace(): boolean;
32
- outputSpace(): this;
33
- inputSpace(): QueryInputSpace;
34
37
  }
35
38
  export declare class ReduceFieldSpace extends QuerySpace {
36
39
  readonly segmentType = "reduce";
@@ -45,9 +45,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
45
45
  return result;
46
46
  };
47
47
  Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.ReduceFieldSpace = exports.QuerySpace = void 0;
48
+ exports.ReduceFieldSpace = exports.QuerySpace = exports.QueryOperationSpace = void 0;
49
49
  const model = __importStar(require("../../../model/malloy_types"));
50
50
  const field_utils_1 = require("../../field-utils");
51
+ const field_space_1 = require("../types/field-space");
51
52
  const space_field_1 = require("../types/space-field");
52
53
  const field_references_1 = require("../query-items/field-references");
53
54
  const refined_space_1 = require("./refined-space");
@@ -55,12 +56,12 @@ const column_space_field_1 = require("./column-space-field");
55
56
  const static_space_1 = require("./static-space");
56
57
  const query_input_space_1 = require("./query-input-space");
57
58
  /**
58
- * The output space of a query operation, it is not named "QueryOutputSpace"
59
- * because this is the namespace of the Query. This is the one which is constructed
60
- * with the query. The QueryInputSpace is created and paired when a
61
- * QuerySpace is created.
59
+ * The output space of a query operation. It is not named "QueryOutputSpace"
60
+ * because this is the namespace of the Query which is a layer of an output and
61
+ * an input space. It constructed with the query operation. A QueryInputSpace is
62
+ * created and paired when a QueryOperationSpace is created.
62
63
  */
63
- class QuerySpace extends refined_space_1.RefinedSpace {
64
+ class QueryOperationSpace extends refined_space_1.RefinedSpace {
64
65
  constructor(queryInputSpace, refineThis, nestParent, astEl) {
65
66
  super(queryInputSpace.emptyStructDef());
66
67
  this.queryInputSpace = queryInputSpace;
@@ -71,45 +72,16 @@ class QuerySpace extends refined_space_1.RefinedSpace {
71
72
  if (refineThis)
72
73
  this.addRefineFromFields(refineThis);
73
74
  }
74
- addRefineFromFields(refineThis) {
75
- var _a, _b;
76
- for (const field of refineThis.fields) {
77
- if (typeof field === 'string') {
78
- const ent = this.exprSpace.entry(field);
79
- if (ent) {
80
- this.setEntry(field, ent);
81
- }
82
- }
83
- else if (model.isFilteredAliasedName(field)) {
84
- const name = (_a = field.as) !== null && _a !== void 0 ? _a : field.name;
85
- const ent = this.exprSpace.entry(name);
86
- if (ent) {
87
- this.setEntry(name, ent);
88
- }
89
- }
90
- else {
91
- // TODO can you reference fields in a turtle as fields in the output space,
92
- // e.g. order_by: my_turtle.foo, or lag(my_turtle.foo)
93
- if (field.type !== 'turtle') {
94
- this.setEntry((_b = field.as) !== null && _b !== void 0 ? _b : field.name, new column_space_field_1.ColumnSpaceField(field));
95
- }
96
- }
97
- }
98
- }
99
75
  log(s) {
100
76
  if (this.astEl) {
101
77
  this.astEl.log(s);
102
78
  }
103
79
  }
104
- pushFields(...defs) {
105
- for (const f of defs) {
106
- if (f instanceof field_references_1.WildcardFieldReference) {
107
- this.addWild(f);
108
- }
109
- else {
110
- super.pushFields(f);
111
- }
112
- }
80
+ inputSpace() {
81
+ return this.exprSpace;
82
+ }
83
+ outputSpace() {
84
+ return this;
113
85
  }
114
86
  addWild(wild) {
115
87
  var _a;
@@ -137,6 +109,7 @@ class QuerySpace extends refined_space_1.RefinedSpace {
137
109
  }
138
110
  }
139
111
  const dialect = this.dialectObj();
112
+ const expandEntries = [];
140
113
  for (const [name, entry] of current.entries()) {
141
114
  if (wild.except.has(name)) {
142
115
  continue;
@@ -150,11 +123,49 @@ class QuerySpace extends refined_space_1.RefinedSpace {
150
123
  if (model.isAtomicFieldType(eType.dataType) &&
151
124
  model.expressionIsScalar(eType.expressionType) &&
152
125
  (dialect === undefined || !dialect.ignoreInProject(name))) {
153
- this.setEntry(name, entry);
126
+ expandEntries.push({ name, entry });
154
127
  this.expandedWild[name] = joinPath.concat(name);
155
128
  }
156
129
  }
157
130
  }
131
+ // There were tests which expected these to be sorted, and that seems reasonable
132
+ for (const x of expandEntries.sort((a, b) => a.name.localeCompare(b.name))) {
133
+ this.setEntry(x.name, x.entry);
134
+ }
135
+ }
136
+ }
137
+ exports.QueryOperationSpace = QueryOperationSpace;
138
+ // Project and Reduce or "QuerySegments" are built from a QuerySpace
139
+ class QuerySpace extends QueryOperationSpace {
140
+ addRefineFromFields(refineThis) {
141
+ var _a;
142
+ if (!model.isQuerySegment(refineThis)) {
143
+ // TODO mtoy raw,partial,index
144
+ return;
145
+ }
146
+ for (const field of refineThis.queryFields) {
147
+ if (field.type === 'fieldref') {
148
+ const refTo = this.exprSpace.lookup(field.path.map(f => new field_space_1.FieldName(f)));
149
+ if (refTo.found) {
150
+ this.setEntry(field.path[field.path.length - 1], refTo.found);
151
+ }
152
+ }
153
+ else if (field.type !== 'turtle') {
154
+ // TODO can you reference fields in a turtle as fields in the output space,
155
+ // e.g. order_by: my_turtle.foo, or lag(my_turtle.foo)
156
+ this.setEntry((_a = field.as) !== null && _a !== void 0 ? _a : field.name, new column_space_field_1.ColumnSpaceField(field));
157
+ }
158
+ }
159
+ }
160
+ pushFields(...defs) {
161
+ for (const f of defs) {
162
+ if (f instanceof field_references_1.WildcardFieldReference) {
163
+ this.addWild(f);
164
+ }
165
+ else {
166
+ super.pushFields(f);
167
+ }
168
+ }
158
169
  }
159
170
  canContain(_typeDesc) {
160
171
  return true;
@@ -165,7 +176,7 @@ class QuerySpace extends refined_space_1.RefinedSpace {
165
176
  if (field instanceof space_field_1.SpaceField) {
166
177
  const wildPath = this.expandedWild[name];
167
178
  if (wildPath) {
168
- fields.push(wildPath.join('.'));
179
+ fields.push({ type: 'fieldref', path: wildPath });
169
180
  continue;
170
181
  }
171
182
  const fieldQueryDef = field.getQueryFieldDef(this.exprSpace);
@@ -202,8 +213,9 @@ class QuerySpace extends refined_space_1.RefinedSpace {
202
213
  }
203
214
  getPipeSegment(refineFrom) {
204
215
  if (this.segmentType === 'index') {
205
- // TODO ... should make this go away
206
- throw new Error('INDEX FIELD PIPE SEGMENT MIS HANDLED');
216
+ // come coding error made this "impossible" thing happen
217
+ this.log('internal error generating index segment from non index query');
218
+ return { type: 'reduce', queryFields: [] };
207
219
  }
208
220
  if (refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.extendSource) {
209
221
  for (const xField of refineFrom.extendSource) {
@@ -212,9 +224,9 @@ class QuerySpace extends refined_space_1.RefinedSpace {
212
224
  }
213
225
  const segment = {
214
226
  type: this.segmentType,
215
- fields: this.queryFieldDefs(),
227
+ queryFields: this.queryFieldDefs(),
216
228
  };
217
- segment.fields = (0, field_utils_1.mergeFields)(refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.fields, segment.fields);
229
+ segment.queryFields = (0, field_utils_1.mergeFields)(refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.queryFields, segment.queryFields);
218
230
  if (refineFrom === null || refineFrom === void 0 ? void 0 : refineFrom.extendSource) {
219
231
  segment.extendSource = refineFrom.extendSource;
220
232
  }
@@ -222,7 +234,7 @@ class QuerySpace extends refined_space_1.RefinedSpace {
222
234
  const newExtends = [];
223
235
  const extendedStruct = this.exprSpace.structDef();
224
236
  for (const extendName of this.exprSpace.extendList) {
225
- const extendEnt = extendedStruct.fields.find(f => (0, field_utils_1.nameOf)(f) === extendName);
237
+ const extendEnt = extendedStruct.fields.find(f => (0, field_utils_1.nameFromDef)(f) === extendName);
226
238
  if (extendEnt) {
227
239
  newExtends.push(extendEnt);
228
240
  }
@@ -245,12 +257,6 @@ class QuerySpace extends refined_space_1.RefinedSpace {
245
257
  isQueryFieldSpace() {
246
258
  return true;
247
259
  }
248
- outputSpace() {
249
- return this;
250
- }
251
- inputSpace() {
252
- return this.exprSpace;
253
- }
254
260
  }
255
261
  exports.QuerySpace = QuerySpace;
256
262
  class ReduceFieldSpace extends QuerySpace {
@@ -261,9 +267,6 @@ class ReduceFieldSpace extends QuerySpace {
261
267
  }
262
268
  exports.ReduceFieldSpace = ReduceFieldSpace;
263
269
  function isEmptyNest(fd) {
264
- return (typeof fd !== 'string' &&
265
- !model.isFilteredAliasedName(fd) &&
266
- fd.type === 'turtle' &&
267
- fd.pipeline.length === 0);
270
+ return (typeof fd !== 'string' && fd.type === 'turtle' && fd.pipeline.length === 0);
268
271
  }
269
272
  //# sourceMappingURL=query-spaces.js.map