@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.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -3
- package/dist/lang/ast/error-factory.js +3 -3
- package/dist/lang/ast/expressions/expr-aggregate-function.d.ts +6 -4
- package/dist/lang/ast/expressions/expr-aggregate-function.js +24 -13
- package/dist/lang/ast/expressions/expr-count.js +1 -1
- package/dist/lang/ast/expressions/expr-func.js +4 -4
- package/dist/lang/ast/expressions/expr-id-reference.js +2 -2
- package/dist/lang/ast/field-space/dynamic-space.js +1 -1
- package/dist/lang/ast/field-space/index-field-space.d.ts +5 -3
- package/dist/lang/ast/field-space/index-field-space.js +85 -16
- package/dist/lang/ast/field-space/query-input-space.d.ts +3 -3
- package/dist/lang/ast/field-space/query-spaces.d.ts +15 -12
- package/dist/lang/ast/field-space/query-spaces.js +60 -57
- package/dist/lang/ast/field-space/reference-field.d.ts +0 -5
- package/dist/lang/ast/field-space/reference-field.js +16 -46
- package/dist/lang/ast/query-builders/index-builder.d.ts +2 -2
- package/dist/lang/ast/query-builders/partial-builder.js +28 -1
- package/dist/lang/ast/query-builders/project-builder.d.ts +8 -4
- package/dist/lang/ast/query-builders/project-builder.js +5 -6
- package/dist/lang/ast/query-builders/reduce-builder.d.ts +13 -8
- package/dist/lang/ast/query-builders/reduce-builder.js +12 -9
- package/dist/lang/ast/query-items/field-declaration.d.ts +1 -1
- package/dist/lang/ast/query-items/field-references.d.ts +5 -1
- package/dist/lang/ast/query-items/field-references.js +17 -1
- package/dist/lang/ast/query-properties/qop-desc.d.ts +2 -2
- package/dist/lang/ast/source-properties/joins.js +1 -1
- package/dist/lang/ast/types/field-space.d.ts +2 -2
- package/dist/lang/ast/types/query-builder.d.ts +2 -2
- package/dist/lang/ast/view-elements/qop-desc-view.d.ts +3 -3
- package/dist/lang/ast/view-elements/reference-view.d.ts +3 -3
- package/dist/lang/ast/view-elements/reference-view.js +1 -1
- package/dist/lang/ast/view-elements/refine-utils.js +20 -18
- package/dist/lang/ast/view-elements/view-arrow.d.ts +2 -2
- package/dist/lang/ast/view-elements/view-refine.d.ts +3 -3
- package/dist/lang/ast/view-elements/view.d.ts +4 -4
- package/dist/lang/field-utils.d.ts +3 -3
- package/dist/lang/field-utils.js +9 -8
- package/dist/lang/test/annotation.spec.js +26 -27
- package/dist/lang/test/expressions.spec.js +43 -40
- package/dist/lang/test/field-symbols.spec.js +4 -4
- package/dist/lang/test/locations.spec.js +13 -6
- package/dist/lang/test/query.spec.js +44 -56
- package/dist/lang/test/test-translator.d.ts +3 -2
- package/dist/lang/test/test-translator.js +30 -24
- package/dist/malloy.js +1 -1
- package/dist/model/malloy_query.d.ts +14 -36
- package/dist/model/malloy_query.js +145 -312
- package/dist/model/malloy_types.d.ts +18 -23
- package/dist/model/malloy_types.js +2 -15
- package/dist/tags.js +19 -4
- 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,
|
|
4
|
-
export { Segment,
|
|
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.
|
|
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',
|
|
54
|
+
return { type: 'reduce', queryFields: [] };
|
|
55
55
|
}
|
|
56
56
|
static get projectSegment() {
|
|
57
|
-
return { type: 'project',
|
|
57
|
+
return { type: 'project', queryFields: [] };
|
|
58
58
|
}
|
|
59
59
|
static get indexSegment() {
|
|
60
|
-
return { type: 'index',
|
|
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.
|
|
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.
|
|
79
|
+
path: this.source.path,
|
|
80
80
|
},
|
|
81
81
|
],
|
|
82
82
|
evalSpace: footType.evalSpace,
|
|
83
83
|
};
|
|
84
|
-
structPath = this.source.
|
|
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
|
|
90
|
-
|
|
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 =
|
|
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.
|
|
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
|
|
183
|
-
const
|
|
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
|
|
201
|
+
const restDef = lookup(def.fieldSpace, rest);
|
|
191
202
|
return {
|
|
192
203
|
...restDef,
|
|
193
204
|
relationship: [
|
|
@@ -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.
|
|
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.
|
|
94
|
+
value: [{ type: 'field', path: this.source.path }],
|
|
95
95
|
evalSpace: footType.evalSpace,
|
|
96
96
|
};
|
|
97
|
-
structPath = this.source.
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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 {
|
|
4
|
-
export declare class IndexFieldSpace extends
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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 {
|
|
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:
|
|
23
|
+
constructor(input: SourceSpec, queryOutput: QueryOperationSpace);
|
|
24
24
|
extendSource(extendField: Join | AtomicFieldDeclaration): void;
|
|
25
25
|
isQueryFieldSpace(): boolean;
|
|
26
|
-
outputSpace():
|
|
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
|
|
10
|
-
* because this is the namespace of the Query
|
|
11
|
-
* with the query.
|
|
12
|
-
*
|
|
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
|
|
14
|
+
export declare abstract class QueryOperationSpace extends RefinedSpace implements QueryFieldSpace {
|
|
15
15
|
readonly queryInputSpace: FieldSpace;
|
|
16
|
-
readonly nestParent:
|
|
16
|
+
readonly nestParent: QueryOperationSpace | undefined;
|
|
17
17
|
readonly astEl: MalloyElement;
|
|
18
|
-
|
|
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:
|
|
22
|
-
|
|
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
|
-
|
|
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
|
|
59
|
-
* because this is the namespace of the Query
|
|
60
|
-
* with the query.
|
|
61
|
-
*
|
|
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
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
//
|
|
206
|
-
|
|
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
|
-
|
|
227
|
+
queryFields: this.queryFieldDefs(),
|
|
216
228
|
};
|
|
217
|
-
segment.
|
|
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.
|
|
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
|