@malloydata/malloy 0.0.270 → 0.0.271-experiment-250430155127
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/ast-utils.js +1 -2
- package/dist/lang/ast/expressions/expr-aggregate-function.js +18 -3
- package/dist/lang/ast/expressions/expr-count-distinct.js +1 -1
- package/dist/lang/ast/expressions/expr-count.js +3 -3
- package/dist/lang/ast/expressions/expr-filter-expr.js +1 -1
- package/dist/lang/ast/expressions/expr-func.js +12 -4
- package/dist/lang/ast/expressions/expr-id-reference.js +24 -11
- package/dist/lang/ast/expressions/expr-now.js +1 -2
- package/dist/lang/ast/expressions/expr-props.d.ts +169 -1
- package/dist/lang/ast/expressions/expr-props.js +35 -2
- package/dist/lang/ast/expressions/expr-ungroup.js +15 -2
- package/dist/lang/ast/expressions/grouped_by.d.ts +7 -0
- package/dist/lang/ast/expressions/grouped_by.js +19 -0
- package/dist/lang/ast/field-space/index-field-space.js +8 -12
- package/dist/lang/ast/field-space/query-spaces.d.ts +7 -10
- package/dist/lang/ast/field-space/query-spaces.js +30 -45
- package/dist/lang/ast/field-space/reference-field.js +16 -3
- package/dist/lang/ast/field-space/struct-space-field-base.js +2 -3
- package/dist/lang/ast/field-space/view-field.d.ts +48 -12
- package/dist/lang/ast/field-space/view-field.js +2 -2
- package/dist/lang/ast/index.d.ts +1 -0
- package/dist/lang/ast/index.js +1 -0
- package/dist/lang/ast/query-builders/index-builder.d.ts +3 -2
- package/dist/lang/ast/query-builders/index-builder.js +7 -6
- package/dist/lang/ast/query-builders/reduce-builder.d.ts +3 -2
- package/dist/lang/ast/query-builders/reduce-builder.js +5 -6
- package/dist/lang/ast/query-elements/query-arrow.js +11 -1
- package/dist/lang/ast/query-elements/query-base.d.ts +2 -2
- package/dist/lang/ast/query-elements/query-base.js +26 -9
- package/dist/lang/ast/query-elements/query-refine.js +1 -1
- package/dist/lang/ast/query-items/field-declaration.js +20 -2
- package/dist/lang/ast/query-items/field-references.d.ts +4 -0
- package/dist/lang/ast/query-items/field-references.js +12 -1
- package/dist/lang/ast/query-properties/filters.js +3 -3
- package/dist/lang/ast/query-properties/nest.js +3 -3
- package/dist/lang/ast/query-utils.d.ts +2 -0
- package/dist/lang/ast/query-utils.js +31 -1
- package/dist/lang/ast/source-elements/composite-source.js +4 -1
- package/dist/lang/ast/source-elements/sql-source.js +8 -1
- package/dist/lang/ast/source-elements/table-source.js +8 -4
- package/dist/lang/ast/source-properties/join.js +3 -2
- package/dist/lang/ast/typedesc-utils.js +1 -2
- package/dist/lang/ast/types/expr-value.d.ts +3 -1
- package/dist/lang/ast/types/expr-value.js +42 -4
- package/dist/lang/ast/types/field-prop-statement.d.ts +2 -1
- package/dist/lang/ast/types/field-prop-statement.js +3 -1
- package/dist/lang/ast/types/query-builder.d.ts +1 -0
- package/dist/lang/ast/types/space-field.js +6 -6
- package/dist/lang/ast/types/space-param.js +2 -3
- package/dist/lang/ast/view-elements/qop-desc-view.js +4 -2
- package/dist/lang/ast/view-elements/reference-view.d.ts +1 -1
- package/dist/lang/ast/view-elements/reference-view.js +17 -6
- package/dist/lang/ast/view-elements/refine-utils.js +1 -1
- package/dist/lang/ast/view-elements/view-arrow.d.ts +3 -3
- package/dist/lang/ast/view-elements/view-refine.d.ts +2 -2
- package/dist/lang/ast/view-elements/view-refine.js +3 -3
- package/dist/lang/ast/view-elements/view.d.ts +2 -2
- package/dist/lang/lib/Malloy/MalloyLexer.d.ts +161 -160
- package/dist/lang/lib/Malloy/MalloyLexer.js +1356 -1345
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +235 -219
- package/dist/lang/lib/Malloy/MalloyParser.js +2165 -2041
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +11 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +7 -0
- package/dist/lang/malloy-to-ast.d.ts +1 -0
- package/dist/lang/malloy-to-ast.js +8 -0
- package/dist/lang/parse-log.d.ts +7 -3
- package/dist/lang/parse-log.js +4 -4
- package/dist/lang/test/parse-expects.d.ts +2 -2
- package/dist/lang/test/parse-expects.js +5 -4
- package/dist/model/composite_source_utils.d.ts +29 -26
- package/dist/model/composite_source_utils.js +588 -197
- package/dist/model/malloy_query.js +4 -0
- package/dist/model/malloy_types.d.ts +27 -10
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.errorFor = void 0;
|
|
26
|
-
const composite_source_utils_1 = require("../../model/composite_source_utils");
|
|
27
26
|
/**
|
|
28
27
|
* When a translation hits an error, log and return one of these as a value.
|
|
29
28
|
* This will allow the rest of the translation walk to complete. The
|
|
@@ -38,7 +37,7 @@ function errorFor(reason) {
|
|
|
38
37
|
expressionType: 'scalar',
|
|
39
38
|
value: { node: 'error', message: reason },
|
|
40
39
|
evalSpace: 'constant',
|
|
41
|
-
|
|
40
|
+
fieldUsage: [],
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
43
|
exports.errorFor = errorFor;
|
|
@@ -55,6 +55,7 @@ const field_references_1 = require("../query-items/field-references");
|
|
|
55
55
|
const expression_def_1 = require("../types/expression-def");
|
|
56
56
|
const space_field_1 = require("../types/space-field");
|
|
57
57
|
const expr_id_reference_1 = require("./expr-id-reference");
|
|
58
|
+
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
58
59
|
class ExprAggregateFunction extends expression_def_1.ExpressionDef {
|
|
59
60
|
constructor(func, expr, explicitSource) {
|
|
60
61
|
super();
|
|
@@ -84,15 +85,24 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
|
|
|
84
85
|
const footType = sourceFoot.typeDesc();
|
|
85
86
|
if (!(sourceFoot instanceof static_space_1.StructSpaceField)) {
|
|
86
87
|
if ((0, malloy_types_1.isAtomicFieldType)(footType.type)) {
|
|
88
|
+
const footPath = this.source.list.map(x => x.refString);
|
|
87
89
|
expr = this.source;
|
|
88
90
|
exprVal = {
|
|
89
91
|
...TDU.atomicDef(footType),
|
|
90
92
|
expressionType: footType.expressionType,
|
|
91
93
|
value: footType.evalSpace === 'output'
|
|
92
94
|
? { node: 'outputField', name: this.source.refString }
|
|
93
|
-
: {
|
|
95
|
+
: {
|
|
96
|
+
node: 'field',
|
|
97
|
+
path: this.source.path,
|
|
98
|
+
at: this.source.location,
|
|
99
|
+
},
|
|
94
100
|
evalSpace: footType.evalSpace,
|
|
95
|
-
|
|
101
|
+
// TODO ensure that when there's an `expr` but no `source`, that `fieldUsage`
|
|
102
|
+
// still comes along correctly
|
|
103
|
+
fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(footType.fieldUsage, [
|
|
104
|
+
{ path: footPath, at: this.source.location },
|
|
105
|
+
]),
|
|
96
106
|
};
|
|
97
107
|
structPath = this.source.path.slice(0, -1);
|
|
98
108
|
// Here we handle a special case where you write `foo.agg()` and `foo` is a
|
|
@@ -157,6 +167,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
|
|
|
157
167
|
node: 'aggregate',
|
|
158
168
|
function: this.func,
|
|
159
169
|
e: exprVal.value,
|
|
170
|
+
at: this.location,
|
|
160
171
|
};
|
|
161
172
|
if (structPath && structPath.length > 0) {
|
|
162
173
|
f.structPath = structPath;
|
|
@@ -178,7 +189,11 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
|
|
|
178
189
|
if (this.source) {
|
|
179
190
|
const lookup = this.source.getField(fs);
|
|
180
191
|
if (lookup.found) {
|
|
181
|
-
const sfd = {
|
|
192
|
+
const sfd = {
|
|
193
|
+
node: 'field',
|
|
194
|
+
path: this.source.path,
|
|
195
|
+
at: this.source.location,
|
|
196
|
+
};
|
|
182
197
|
result.push(...getJoinUsage(fs, sfd));
|
|
183
198
|
}
|
|
184
199
|
}
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.ExprCount = void 0;
|
|
26
|
-
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
27
26
|
const expr_aggregate_function_1 = require("./expr-aggregate-function");
|
|
28
27
|
class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
|
|
29
28
|
constructor(source) {
|
|
@@ -45,7 +44,7 @@ class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
|
|
|
45
44
|
evalSpace: ev.evalSpace,
|
|
46
45
|
expressionType: 'aggregate',
|
|
47
46
|
value: ev.value,
|
|
48
|
-
|
|
47
|
+
fieldUsage: ev.fieldUsage,
|
|
49
48
|
};
|
|
50
49
|
}
|
|
51
50
|
getExpression(_fs) {
|
|
@@ -53,6 +52,7 @@ class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
|
|
|
53
52
|
node: 'aggregate',
|
|
54
53
|
function: 'count',
|
|
55
54
|
e: { node: '' },
|
|
55
|
+
at: this.location,
|
|
56
56
|
};
|
|
57
57
|
if (this.source) {
|
|
58
58
|
ret.structPath = this.source.path;
|
|
@@ -63,7 +63,7 @@ class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
|
|
|
63
63
|
expressionType: 'aggregate',
|
|
64
64
|
value: ret,
|
|
65
65
|
evalSpace: 'output',
|
|
66
|
-
|
|
66
|
+
fieldUsage: [],
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -20,7 +20,7 @@ class ExprFilterExpression extends expression_def_1.ExpressionDef {
|
|
|
20
20
|
value: { node: 'filterLiteral', filterSrc: this.filterText },
|
|
21
21
|
expressionType: 'scalar',
|
|
22
22
|
evalSpace: 'constant',
|
|
23
|
-
|
|
23
|
+
fieldUsage: [],
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -140,9 +140,13 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
140
140
|
implicitExpr = {
|
|
141
141
|
...TDU.atomicDef(footType),
|
|
142
142
|
expressionType: footType.expressionType,
|
|
143
|
-
value: {
|
|
143
|
+
value: {
|
|
144
|
+
node: 'field',
|
|
145
|
+
path: this.source.path,
|
|
146
|
+
at: this.source.location,
|
|
147
|
+
},
|
|
144
148
|
evalSpace: footType.evalSpace,
|
|
145
|
-
|
|
149
|
+
fieldUsage: footType.fieldUsage,
|
|
146
150
|
};
|
|
147
151
|
structPath = this.source.path.slice(0, -1);
|
|
148
152
|
}
|
|
@@ -316,7 +320,11 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
316
320
|
expr.push({ node: 'parameter', path: [part.name] });
|
|
317
321
|
}
|
|
318
322
|
else {
|
|
319
|
-
expr.push({
|
|
323
|
+
expr.push({
|
|
324
|
+
node: 'field',
|
|
325
|
+
path: [part.name],
|
|
326
|
+
at: this.args[0].location,
|
|
327
|
+
});
|
|
320
328
|
}
|
|
321
329
|
}
|
|
322
330
|
}
|
|
@@ -342,7 +350,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
342
350
|
expressionType,
|
|
343
351
|
value: funcCall,
|
|
344
352
|
evalSpace,
|
|
345
|
-
|
|
353
|
+
fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(...argExprs.map(e => e.fieldUsage)),
|
|
346
354
|
};
|
|
347
355
|
}
|
|
348
356
|
}
|
|
@@ -25,7 +25,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.ExprIdReference = void 0;
|
|
26
26
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
27
|
const expression_def_1 = require("../types/expression-def");
|
|
28
|
-
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
29
28
|
class ExprIdReference extends expression_def_1.ExpressionDef {
|
|
30
29
|
constructor(fieldReference) {
|
|
31
30
|
super();
|
|
@@ -38,30 +37,44 @@ class ExprIdReference extends expression_def_1.ExpressionDef {
|
|
|
38
37
|
}
|
|
39
38
|
getExpression(fs) {
|
|
40
39
|
const def = this.fieldReference.getField(fs);
|
|
41
|
-
// TODO Currently the join usage is always equivalent to the reference path here;
|
|
42
|
-
// if/when we add namespaces, this will not be the case, and we will need to get the
|
|
43
|
-
// join path from `getField` / `lookup`
|
|
44
|
-
const compositeJoinUsage = this.fieldReference.list
|
|
45
|
-
.map(n => n.name)
|
|
46
|
-
.slice(0, -1);
|
|
47
40
|
if (def.found) {
|
|
41
|
+
// TODO Currently the join usage is always equivalent to the reference path here;
|
|
42
|
+
// if/when we add namespaces, this will not be the case, and we will need to get the
|
|
43
|
+
// join path from `getField` / `lookup`
|
|
44
|
+
const fieldUsage = def.found.refType === 'field'
|
|
45
|
+
? [
|
|
46
|
+
{
|
|
47
|
+
path: this.fieldReference.list.map(n => n.name),
|
|
48
|
+
at: this.fieldReference.location,
|
|
49
|
+
},
|
|
50
|
+
]
|
|
51
|
+
: [];
|
|
48
52
|
const td = def.found.typeDesc();
|
|
49
|
-
const compositeFieldUsage = (0, composite_source_utils_1.joinedCompositeFieldUsage)(compositeJoinUsage, td.compositeFieldUsage);
|
|
50
53
|
if (def.isOutputField) {
|
|
51
54
|
return {
|
|
52
55
|
...td,
|
|
53
56
|
// TODO what about literal??
|
|
54
57
|
evalSpace: td.evalSpace === 'constant' ? 'constant' : 'output',
|
|
55
58
|
value: { node: 'outputField', name: this.refString },
|
|
56
|
-
|
|
59
|
+
fieldUsage,
|
|
57
60
|
};
|
|
58
61
|
}
|
|
59
|
-
const value = {
|
|
62
|
+
const value = {
|
|
63
|
+
node: def.found.refType,
|
|
64
|
+
path: this.fieldReference.path,
|
|
65
|
+
at: this.fieldReference.location,
|
|
66
|
+
};
|
|
60
67
|
// We think that aggregates are more 'output' like, but maybe we will reconsider that...
|
|
61
68
|
const evalSpace = (0, malloy_types_1.expressionIsAggregate)(td.expressionType)
|
|
62
69
|
? 'output'
|
|
63
70
|
: td.evalSpace;
|
|
64
|
-
return {
|
|
71
|
+
return {
|
|
72
|
+
...td,
|
|
73
|
+
value,
|
|
74
|
+
evalSpace,
|
|
75
|
+
fieldUsage,
|
|
76
|
+
requiresGroupBy: undefined,
|
|
77
|
+
};
|
|
65
78
|
}
|
|
66
79
|
return this.loggedErrorExpr(def.error.code, def.error.message);
|
|
67
80
|
}
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.ExprNow = void 0;
|
|
26
26
|
const expression_def_1 = require("../types/expression-def");
|
|
27
|
-
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
28
27
|
class ExprNow extends expression_def_1.ExpressionDef {
|
|
29
28
|
constructor() {
|
|
30
29
|
super(...arguments);
|
|
@@ -37,7 +36,7 @@ class ExprNow extends expression_def_1.ExpressionDef {
|
|
|
37
36
|
// `now` is considered to be a constant, at least in the dialects we support today
|
|
38
37
|
evalSpace: 'constant',
|
|
39
38
|
value: { node: 'now', typeDef: { type: 'timestamp' } },
|
|
40
|
-
|
|
39
|
+
fieldUsage: [],
|
|
41
40
|
};
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ExprValue } from '../types/expr-value';
|
|
2
2
|
import { ExpressionDef } from '../types/expression-def';
|
|
3
3
|
import type { FieldPropStatement } from '../types/field-prop-statement';
|
|
4
4
|
import type { FieldSpace } from '../types/field-space';
|
|
5
|
+
import { GroupedBy } from './grouped_by';
|
|
5
6
|
export declare class ExprProps extends ExpressionDef {
|
|
6
7
|
readonly expr: ExpressionDef;
|
|
7
8
|
readonly statements: FieldPropStatement[];
|
|
@@ -10,4 +11,171 @@ export declare class ExprProps extends ExpressionDef {
|
|
|
10
11
|
constructor(expr: ExpressionDef, statements: FieldPropStatement[]);
|
|
11
12
|
private getFilteredExpression;
|
|
12
13
|
getExpression(fs: FieldSpace): ExprValue;
|
|
14
|
+
getGroupedBys(fs: FieldSpace, expr: ExprValue, groupedBys: GroupedBy[]): {
|
|
15
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
16
|
+
type: "string";
|
|
17
|
+
bucketFilter?: string | undefined;
|
|
18
|
+
bucketOther?: string | undefined;
|
|
19
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
20
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
21
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
22
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
23
|
+
value: import("../../../model/malloy_types").Expr;
|
|
24
|
+
morphic?: {
|
|
25
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
26
|
+
} | undefined;
|
|
27
|
+
} | {
|
|
28
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
29
|
+
type: "date";
|
|
30
|
+
timeframe?: import("../../../model/malloy_types").DateUnit | undefined;
|
|
31
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
32
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
33
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
34
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
35
|
+
value: import("../../../model/malloy_types").Expr;
|
|
36
|
+
morphic?: {
|
|
37
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
38
|
+
} | undefined;
|
|
39
|
+
} | {
|
|
40
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
41
|
+
type: "timestamp";
|
|
42
|
+
timeframe?: import("../../../model/malloy_types").TimestampUnit | undefined;
|
|
43
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
44
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
45
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
46
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
47
|
+
value: import("../../../model/malloy_types").Expr;
|
|
48
|
+
morphic?: {
|
|
49
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
50
|
+
} | undefined;
|
|
51
|
+
} | {
|
|
52
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
53
|
+
type: "number";
|
|
54
|
+
numberType?: "integer" | "float" | undefined;
|
|
55
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
56
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
57
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
58
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
59
|
+
value: import("../../../model/malloy_types").Expr;
|
|
60
|
+
morphic?: {
|
|
61
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
62
|
+
} | undefined;
|
|
63
|
+
} | {
|
|
64
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
65
|
+
type: "boolean";
|
|
66
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
67
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
68
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
69
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
70
|
+
value: import("../../../model/malloy_types").Expr;
|
|
71
|
+
morphic?: {
|
|
72
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
73
|
+
} | undefined;
|
|
74
|
+
} | {
|
|
75
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
76
|
+
type: "json";
|
|
77
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
78
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
79
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
80
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
81
|
+
value: import("../../../model/malloy_types").Expr;
|
|
82
|
+
morphic?: {
|
|
83
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
84
|
+
} | undefined;
|
|
85
|
+
} | {
|
|
86
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
87
|
+
type: "sql native";
|
|
88
|
+
rawType?: string | undefined;
|
|
89
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
90
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
91
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
92
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
93
|
+
value: import("../../../model/malloy_types").Expr;
|
|
94
|
+
morphic?: {
|
|
95
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
96
|
+
} | undefined;
|
|
97
|
+
} | {
|
|
98
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
99
|
+
type: "error";
|
|
100
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
101
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
102
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
103
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
104
|
+
value: import("../../../model/malloy_types").Expr;
|
|
105
|
+
morphic?: {
|
|
106
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
107
|
+
} | undefined;
|
|
108
|
+
} | {
|
|
109
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
110
|
+
type: "array";
|
|
111
|
+
elementTypeDef: import("../../../model/malloy_types").BasicAtomicTypeDef | import("../../../model/malloy_types").BasicArrayTypeDef | import("../../../model/malloy_types").RepeatedRecordTypeDef;
|
|
112
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
113
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
114
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
115
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
116
|
+
value: import("../../../model/malloy_types").Expr;
|
|
117
|
+
morphic?: {
|
|
118
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
119
|
+
} | undefined;
|
|
120
|
+
} | {
|
|
121
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
122
|
+
type: "record";
|
|
123
|
+
fields: import("../../../model/malloy_types").FieldDef[];
|
|
124
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
125
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
126
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
127
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
128
|
+
value: import("../../../model/malloy_types").Expr;
|
|
129
|
+
morphic?: {
|
|
130
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
131
|
+
} | undefined;
|
|
132
|
+
} | {
|
|
133
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
134
|
+
type: "array";
|
|
135
|
+
elementTypeDef: import("../../../model/malloy_types").RecordElementTypeDef;
|
|
136
|
+
fields: import("../../../model/malloy_types").FieldDef[];
|
|
137
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
138
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
139
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
140
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
141
|
+
value: import("../../../model/malloy_types").Expr;
|
|
142
|
+
morphic?: {
|
|
143
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
144
|
+
} | undefined;
|
|
145
|
+
} | {
|
|
146
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
147
|
+
type: import("../../../model/malloy_types").NonAtomicType;
|
|
148
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
149
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
150
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
151
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
152
|
+
value: import("../../../model/malloy_types").Expr;
|
|
153
|
+
morphic?: {
|
|
154
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
155
|
+
} | undefined;
|
|
156
|
+
} | {
|
|
157
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
158
|
+
type: "date";
|
|
159
|
+
timeframe?: "day" | "week" | "month" | "quarter" | "year" | undefined;
|
|
160
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
161
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
162
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
163
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
164
|
+
value: import("../../../model/malloy_types").Expr;
|
|
165
|
+
morphic?: {
|
|
166
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
167
|
+
} | undefined;
|
|
168
|
+
} | {
|
|
169
|
+
requiresGroupBy: import("../../../model/malloy_types").RequiredGroupBy[] | undefined;
|
|
170
|
+
type: "timestamp";
|
|
171
|
+
timeframe?: import("../../../model/malloy_types").TimestampUnit | undefined;
|
|
172
|
+
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
173
|
+
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
174
|
+
fieldUsage: import("../../../model/malloy_types").FieldUsage[];
|
|
175
|
+
ungroupings?: import("../../../model/malloy_types").AggregateUngrouping[] | undefined;
|
|
176
|
+
value: import("../../../model/malloy_types").Expr;
|
|
177
|
+
morphic?: {
|
|
178
|
+
[x: string]: import("../../../model/malloy_types").Expr;
|
|
179
|
+
} | undefined;
|
|
180
|
+
};
|
|
13
181
|
}
|
|
@@ -52,9 +52,11 @@ const TDU = __importStar(require("../typedesc-utils"));
|
|
|
52
52
|
const function_ordering_1 = require("./function-ordering");
|
|
53
53
|
const limit_1 = require("../query-properties/limit");
|
|
54
54
|
const partition_by_1 = require("./partition_by");
|
|
55
|
+
const expr_value_1 = require("../types/expr-value");
|
|
55
56
|
const expression_def_1 = require("../types/expression-def");
|
|
56
57
|
const expr_func_1 = require("./expr-func");
|
|
57
58
|
const composite_source_utils_1 = require("../../../model/composite_source_utils");
|
|
59
|
+
const grouped_by_1 = require("./grouped_by");
|
|
58
60
|
class ExprProps extends expression_def_1.ExpressionDef {
|
|
59
61
|
constructor(expr, statements) {
|
|
60
62
|
super({ expr, statements });
|
|
@@ -81,7 +83,7 @@ class ExprProps extends expression_def_1.ExpressionDef {
|
|
|
81
83
|
if (this.typeCheck(this.expr, { ...expr, expressionType: 'scalar' })) {
|
|
82
84
|
return {
|
|
83
85
|
...expr,
|
|
84
|
-
|
|
86
|
+
fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(expr.fieldUsage, ...filterList.map(f => { var _a; return (_a = f.fieldUsage) !== null && _a !== void 0 ? _a : []; })),
|
|
85
87
|
value: {
|
|
86
88
|
node: 'filteredExpr',
|
|
87
89
|
kids: { e: expr.value, filterList },
|
|
@@ -98,6 +100,7 @@ class ExprProps extends expression_def_1.ExpressionDef {
|
|
|
98
100
|
let limit;
|
|
99
101
|
const orderBys = [];
|
|
100
102
|
const wheres = [];
|
|
103
|
+
const groupedBys = [];
|
|
101
104
|
for (const statement of this.statements) {
|
|
102
105
|
if (statement instanceof partition_by_1.PartitionBy) {
|
|
103
106
|
if (!this.expr.canSupportPartitionBy()) {
|
|
@@ -126,6 +129,9 @@ class ExprProps extends expression_def_1.ExpressionDef {
|
|
|
126
129
|
orderBys.push(statement);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
132
|
+
else if (statement instanceof grouped_by_1.GroupedBy) {
|
|
133
|
+
groupedBys.push(statement);
|
|
134
|
+
}
|
|
129
135
|
else {
|
|
130
136
|
wheres.push(statement);
|
|
131
137
|
}
|
|
@@ -137,7 +143,34 @@ class ExprProps extends expression_def_1.ExpressionDef {
|
|
|
137
143
|
orderBys,
|
|
138
144
|
})
|
|
139
145
|
: this.expr.getExpression(fs);
|
|
140
|
-
|
|
146
|
+
const filteredExpr = this.getFilteredExpression(fs, resultExpr, wheres);
|
|
147
|
+
return this.getGroupedBys(fs, filteredExpr, groupedBys);
|
|
148
|
+
}
|
|
149
|
+
getGroupedBys(fs, expr, groupedBys) {
|
|
150
|
+
const groupedByFields = [];
|
|
151
|
+
for (const requiredGroupBy of groupedBys) {
|
|
152
|
+
for (const field of requiredGroupBy.groupedByFields) {
|
|
153
|
+
const e = field.getField(fs);
|
|
154
|
+
if (e.found === undefined) {
|
|
155
|
+
field.logError('grouped-by-not-found', `${field.refString} is not defined`);
|
|
156
|
+
}
|
|
157
|
+
else if ((0, malloy_types_1.expressionIsAnalytic)(e.found.typeDesc().expressionType) ||
|
|
158
|
+
(0, malloy_types_1.expressionIsAggregate)(e.found.typeDesc().expressionType)) {
|
|
159
|
+
field.logError('non-scalar-grouped-by', '`grouped_by:` field must be a dimension');
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
groupedByFields.push(field.nameString);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const allRequiredGroupBys = (0, expr_value_1.mergeGroupedBys)(expr.requiresGroupBy, groupedByFields.map(name => ({
|
|
167
|
+
path: [name],
|
|
168
|
+
at: this.location,
|
|
169
|
+
})));
|
|
170
|
+
return {
|
|
171
|
+
...expr,
|
|
172
|
+
requiresGroupBy: allRequiredGroupBys,
|
|
173
|
+
};
|
|
141
174
|
}
|
|
142
175
|
}
|
|
143
176
|
exports.ExprProps = ExprProps;
|
|
@@ -48,6 +48,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
48
48
|
exports.ExprUngroup = void 0;
|
|
49
49
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
50
50
|
const query_spaces_1 = require("../field-space/query-spaces");
|
|
51
|
+
const reference_field_1 = require("../field-space/reference-field");
|
|
51
52
|
const TDU = __importStar(require("../typedesc-utils"));
|
|
52
53
|
const expression_def_1 = require("../types/expression-def");
|
|
53
54
|
class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
@@ -60,6 +61,7 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
60
61
|
this.elementType = 'ungroup';
|
|
61
62
|
}
|
|
62
63
|
getExpression(fs) {
|
|
64
|
+
var _a, _b;
|
|
63
65
|
const exprVal = this.expr.getExpression(fs);
|
|
64
66
|
if (!(0, malloy_types_1.expressionIsAggregate)(exprVal.expressionType)) {
|
|
65
67
|
return this.expr.loggedErrorExpr('ungroup-of-non-aggregate', `${this.control}() expression must be an aggregate`);
|
|
@@ -71,13 +73,14 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
71
73
|
node: this.control,
|
|
72
74
|
e: exprVal.value,
|
|
73
75
|
};
|
|
76
|
+
const ungroupFields = [];
|
|
74
77
|
if (this.typeCheck(this.expr, { ...exprVal, expressionType: 'scalar' })) {
|
|
78
|
+
const isExclude = this.control === 'exclude';
|
|
75
79
|
// Now every mentioned field must be in the output space of one of the queries
|
|
76
80
|
// of the nest tree leading to this query. If this is a source definition,
|
|
77
81
|
// this is not checked until sql generation time.
|
|
78
82
|
if (fs.isQueryFieldSpace() && this.fields.length > 0) {
|
|
79
83
|
const dstFields = [];
|
|
80
|
-
const isExclude = this.control === 'exclude';
|
|
81
84
|
for (const mentionedField of this.fields) {
|
|
82
85
|
let ofs = fs.outputSpace();
|
|
83
86
|
let notFound = true;
|
|
@@ -85,6 +88,9 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
85
88
|
const entryInfo = ofs.lookup([mentionedField]);
|
|
86
89
|
if (entryInfo.found && entryInfo.isOutputField) {
|
|
87
90
|
dstFields.push(mentionedField.refString);
|
|
91
|
+
if (entryInfo.found instanceof reference_field_1.ReferenceField) {
|
|
92
|
+
ungroupFields.push(entryInfo.found.fieldRef.list.map(n => n.refString));
|
|
93
|
+
}
|
|
88
94
|
notFound = false;
|
|
89
95
|
}
|
|
90
96
|
else if (ofs instanceof query_spaces_1.QuerySpace) {
|
|
@@ -106,7 +112,14 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
|
|
|
106
112
|
expressionType: 'ungrouped_aggregate',
|
|
107
113
|
value: ungroup,
|
|
108
114
|
evalSpace: 'output',
|
|
109
|
-
|
|
115
|
+
fieldUsage: exprVal.fieldUsage,
|
|
116
|
+
ungroupings: [
|
|
117
|
+
{
|
|
118
|
+
requiresGroupBy: (_a = exprVal.requiresGroupBy) !== null && _a !== void 0 ? _a : [],
|
|
119
|
+
fieldUsage: (_b = exprVal.fieldUsage) !== null && _b !== void 0 ? _b : [],
|
|
120
|
+
ungroupedFields: isExclude ? ungroupFields !== null && ungroupFields !== void 0 ? ungroupFields : [] : '*',
|
|
121
|
+
},
|
|
122
|
+
],
|
|
110
123
|
};
|
|
111
124
|
}
|
|
112
125
|
return this.loggedErrorExpr('ungroup-with-non-scalar', `${this.control}() incompatible type`);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GroupedByReference } from '../query-items/field-references';
|
|
2
|
+
import { ListOf } from '../types/malloy-element';
|
|
3
|
+
export declare class GroupedBy extends ListOf<GroupedByReference> {
|
|
4
|
+
readonly groupedByFields: GroupedByReference[];
|
|
5
|
+
elementType: string;
|
|
6
|
+
constructor(groupedByFields: GroupedByReference[]);
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.GroupedBy = void 0;
|
|
10
|
+
const malloy_element_1 = require("../types/malloy-element");
|
|
11
|
+
class GroupedBy extends malloy_element_1.ListOf {
|
|
12
|
+
constructor(groupedByFields) {
|
|
13
|
+
super(groupedByFields);
|
|
14
|
+
this.groupedByFields = groupedByFields;
|
|
15
|
+
this.elementType = 'require_group_by';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.GroupedBy = GroupedBy;
|
|
19
|
+
//# sourceMappingURL=grouped_by.js.map
|
|
@@ -53,18 +53,17 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
|
|
|
53
53
|
this.logError('refinement-of-index-segment', 'index query operations cannot be refined');
|
|
54
54
|
return { type: 'index', indexFields: [] };
|
|
55
55
|
}
|
|
56
|
-
let
|
|
57
|
-
let narrowedCompositeFieldResolution = (0, composite_source_utils_1.emptyNarrowedCompositeFieldResolution)();
|
|
56
|
+
let fieldUsage = (0, composite_source_utils_1.emptyFieldUsage)();
|
|
58
57
|
const indexFields = [];
|
|
59
58
|
const source = this.inputSpace().structDef();
|
|
60
59
|
for (const [name, field] of this.entries()) {
|
|
61
60
|
if (field instanceof space_field_1.SpaceField) {
|
|
62
|
-
let
|
|
61
|
+
let nextFieldUsage = undefined;
|
|
63
62
|
let logTo = undefined;
|
|
64
63
|
const wild = this.expandedWild[name];
|
|
65
64
|
if (wild) {
|
|
66
|
-
indexFields.push({ type: 'fieldref', path: wild.path });
|
|
67
|
-
|
|
65
|
+
indexFields.push({ type: 'fieldref', path: wild.path, at: wild.at });
|
|
66
|
+
nextFieldUsage = wild.entry.typeDesc().fieldUsage;
|
|
68
67
|
}
|
|
69
68
|
else if (field instanceof reference_field_1.ReferenceField) {
|
|
70
69
|
// attempt to cause a type check
|
|
@@ -75,18 +74,14 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
|
|
|
75
74
|
}
|
|
76
75
|
else {
|
|
77
76
|
indexFields.push(fieldRef.refToField);
|
|
78
|
-
|
|
79
|
-
check.found.typeDesc().compositeFieldUsage;
|
|
77
|
+
nextFieldUsage = check.found.typeDesc().fieldUsage;
|
|
80
78
|
logTo = fieldRef;
|
|
81
79
|
}
|
|
82
80
|
}
|
|
83
|
-
|
|
84
|
-
compositeFieldUsage = next.compositeFieldUsage;
|
|
85
|
-
narrowedCompositeFieldResolution =
|
|
86
|
-
next.narrowedCompositeFieldResolution;
|
|
81
|
+
fieldUsage = this.applyNextFieldUsage(source, fieldUsage, nextFieldUsage, logTo);
|
|
87
82
|
}
|
|
88
83
|
}
|
|
89
|
-
this.
|
|
84
|
+
this._fieldUsage = fieldUsage;
|
|
90
85
|
return { type: 'index', indexFields };
|
|
91
86
|
}
|
|
92
87
|
addRefineFromFields(_refineThis) { }
|
|
@@ -142,6 +137,7 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
|
|
|
142
137
|
this.expandedWild[indexName] = {
|
|
143
138
|
path: joinPath.concat(name),
|
|
144
139
|
entry,
|
|
140
|
+
at: wild.location,
|
|
145
141
|
};
|
|
146
142
|
}
|
|
147
143
|
}
|