@malloydata/malloy 0.0.22-dev230117232218 → 0.0.22-dev230119001546
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/apply-expr.d.ts +1 -14
- package/dist/lang/ast/apply-expr.js +1 -208
- package/dist/lang/ast/ast-expr.d.ts +9 -96
- package/dist/lang/ast/ast-expr.js +105 -384
- package/dist/lang/ast/ast-main.d.ts +141 -1
- package/dist/lang/ast/ast-main.js +681 -9
- package/dist/lang/ast/ast-time-expr.d.ts +2 -41
- package/dist/lang/ast/ast-time-expr.js +36 -204
- package/package.json +1 -1
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
import { TimestampUnit, ExtractUnit, TimeFieldType } from "../../model/malloy_types";
|
|
2
2
|
import { FieldSpace } from "../field-space";
|
|
3
|
-
import {
|
|
3
|
+
import { Comparison, ExprValue } from "./ast-types";
|
|
4
|
+
import { ExpressionDef, MalloyElement } from "./ast-main";
|
|
4
5
|
export declare class Timeframe extends MalloyElement {
|
|
5
6
|
elementType: string;
|
|
6
7
|
readonly text: TimestampUnit;
|
|
7
8
|
constructor(timeframeName: string);
|
|
8
9
|
}
|
|
9
|
-
/**
|
|
10
|
-
* GranularTime is a moment in time which ALSO has a "granularity"
|
|
11
|
-
* commonly this are created by applying ".datePart" to an expression
|
|
12
|
-
* 1) They have a value, which is the moment in time
|
|
13
|
-
* 2) When used in a comparison, they act like a range, for the
|
|
14
|
-
* duration of 1 unit of granularity
|
|
15
|
-
*/
|
|
16
|
-
export declare class ExprGranularTime extends ExpressionDef {
|
|
17
|
-
readonly expr: ExpressionDef;
|
|
18
|
-
readonly units: TimestampUnit;
|
|
19
|
-
readonly truncate: boolean;
|
|
20
|
-
elementType: string;
|
|
21
|
-
legalChildTypes: import("./ast-types").FragType[];
|
|
22
|
-
constructor(expr: ExpressionDef, units: TimestampUnit, truncate: boolean);
|
|
23
|
-
granular(): boolean;
|
|
24
|
-
getExpression(fs: FieldSpace): ExprValue;
|
|
25
|
-
apply(fs: FieldSpace, op: string, left: ExpressionDef): ExprValue;
|
|
26
|
-
protected timestampRange(fs: FieldSpace, op: string, expr: ExpressionDef): ExprValue;
|
|
27
|
-
protected dateRange(fs: FieldSpace, op: string, expr: ExpressionDef): ExprValue;
|
|
28
|
-
}
|
|
29
10
|
/**
|
|
30
11
|
* GranularTime made from a literal. Funky because it doesn't know if it
|
|
31
12
|
* is a date or a timestamp in many cases until it is applied.
|
|
@@ -46,26 +27,6 @@ export declare class ExprNow extends ExpressionDef {
|
|
|
46
27
|
elementType: string;
|
|
47
28
|
getExpression(_fs: FieldSpace): ExprValue;
|
|
48
29
|
}
|
|
49
|
-
export declare class ExprDuration extends ExpressionDef {
|
|
50
|
-
readonly n: ExpressionDef;
|
|
51
|
-
readonly timeframe: TimestampUnit;
|
|
52
|
-
elementType: string;
|
|
53
|
-
legalChildTypes: import("./ast-types").FragType[];
|
|
54
|
-
constructor(n: ExpressionDef, timeframe: TimestampUnit);
|
|
55
|
-
apply(fs: FieldSpace, op: string, left: ExpressionDef): ExprValue;
|
|
56
|
-
getExpression(_fs: FieldSpace): ExprValue;
|
|
57
|
-
}
|
|
58
|
-
export declare class ExprCompare extends BinaryBoolean<Comparison> {
|
|
59
|
-
elementType: string;
|
|
60
|
-
constructor(left: ExpressionDef, op: Comparison, right: ExpressionDef);
|
|
61
|
-
getExpression(fs: FieldSpace): ExprValue;
|
|
62
|
-
}
|
|
63
|
-
export declare class Apply extends ExprCompare {
|
|
64
|
-
readonly left: ExpressionDef;
|
|
65
|
-
readonly right: ExpressionDef;
|
|
66
|
-
elementType: string;
|
|
67
|
-
constructor(left: ExpressionDef, right: ExpressionDef);
|
|
68
|
-
}
|
|
69
30
|
export declare class PartialCompare extends ExpressionDef {
|
|
70
31
|
readonly op: Comparison;
|
|
71
32
|
readonly right: ExpressionDef;
|
|
@@ -22,11 +22,13 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.ExprFunc = exports.ExprTimeExtract = exports.ForRange = exports.PartialCompare = exports.
|
|
25
|
+
exports.ExprFunc = exports.ExprTimeExtract = exports.ForRange = exports.PartialCompare = exports.ExprNow = exports.GranularLiteral = exports.Timeframe = void 0;
|
|
26
26
|
const luxon_1 = require("luxon");
|
|
27
27
|
const malloy_types_1 = require("../../model/malloy_types");
|
|
28
|
-
const
|
|
29
|
-
|
|
28
|
+
const ast_types_1 = require("./ast-types");
|
|
29
|
+
const time_utils_1 = require("./time-utils");
|
|
30
|
+
const ast_main_1 = require("./ast-main");
|
|
31
|
+
class Timeframe extends ast_main_1.MalloyElement {
|
|
30
32
|
constructor(timeframeName) {
|
|
31
33
|
super();
|
|
32
34
|
this.elementType = "timeframe";
|
|
@@ -38,95 +40,11 @@ class Timeframe extends index_1.MalloyElement {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
exports.Timeframe = Timeframe;
|
|
41
|
-
/**
|
|
42
|
-
* GranularTime is a moment in time which ALSO has a "granularity"
|
|
43
|
-
* commonly this are created by applying ".datePart" to an expression
|
|
44
|
-
* 1) They have a value, which is the moment in time
|
|
45
|
-
* 2) When used in a comparison, they act like a range, for the
|
|
46
|
-
* duration of 1 unit of granularity
|
|
47
|
-
*/
|
|
48
|
-
class ExprGranularTime extends index_1.ExpressionDef {
|
|
49
|
-
constructor(expr, units, truncate) {
|
|
50
|
-
super({ expr });
|
|
51
|
-
this.expr = expr;
|
|
52
|
-
this.units = units;
|
|
53
|
-
this.truncate = truncate;
|
|
54
|
-
this.elementType = "granularTime";
|
|
55
|
-
this.legalChildTypes = [index_1.FT.timestampT, index_1.FT.dateT];
|
|
56
|
-
}
|
|
57
|
-
granular() {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
getExpression(fs) {
|
|
61
|
-
const timeframe = this.units;
|
|
62
|
-
const exprVal = this.expr.getExpression(fs);
|
|
63
|
-
if ((0, malloy_types_1.isTimeFieldType)(exprVal.dataType)) {
|
|
64
|
-
const tsVal = {
|
|
65
|
-
...exprVal,
|
|
66
|
-
dataType: exprVal.dataType,
|
|
67
|
-
timeframe: timeframe,
|
|
68
|
-
};
|
|
69
|
-
if (this.truncate) {
|
|
70
|
-
tsVal.value = [
|
|
71
|
-
{
|
|
72
|
-
type: "dialect",
|
|
73
|
-
function: "trunc",
|
|
74
|
-
expr: { value: exprVal.value, valueType: exprVal.dataType },
|
|
75
|
-
units: timeframe,
|
|
76
|
-
},
|
|
77
|
-
];
|
|
78
|
-
}
|
|
79
|
-
return tsVal;
|
|
80
|
-
}
|
|
81
|
-
this.log(`Cannot do time truncation on type '${exprVal.dataType}'`);
|
|
82
|
-
return (0, index_1.errorFor)(`granularity typecheck`);
|
|
83
|
-
}
|
|
84
|
-
apply(fs, op, left) {
|
|
85
|
-
const rangeType = this.getExpression(fs).dataType;
|
|
86
|
-
const _valueType = left.getExpression(fs).dataType;
|
|
87
|
-
const granularityType = (0, malloy_types_1.isDateUnit)(this.units) ? "date" : "timestamp";
|
|
88
|
-
if (rangeType == "date" && granularityType == "date") {
|
|
89
|
-
return this.dateRange(fs, op, left);
|
|
90
|
-
}
|
|
91
|
-
return this.timestampRange(fs, op, left);
|
|
92
|
-
/*
|
|
93
|
-
write tests for each of these cases ....
|
|
94
|
-
|
|
95
|
-
vt rt gt use
|
|
96
|
-
dt dt dt dateRange
|
|
97
|
-
dt dt ts == or timeStampRange
|
|
98
|
-
dt ts dt timestampRange
|
|
99
|
-
dt ts ts timeStampRange
|
|
100
|
-
|
|
101
|
-
ts ts ts timestampRange
|
|
102
|
-
ts ts dt timestampRange
|
|
103
|
-
ts dt ts timestampRange
|
|
104
|
-
ts dt dt either
|
|
105
|
-
|
|
106
|
-
*/
|
|
107
|
-
}
|
|
108
|
-
timestampRange(fs, op, expr) {
|
|
109
|
-
const begin = this.getExpression(fs);
|
|
110
|
-
const beginTime = index_1.ExprTime.fromValue("timestamp", begin);
|
|
111
|
-
const endTime = new index_1.ExprTime("timestamp", (0, index_1.timeOffset)("timestamp", begin.value, "+", (0, malloy_types_1.mkExpr) `1`, this.units), begin.expressionType);
|
|
112
|
-
const range = new index_1.Range(beginTime, endTime);
|
|
113
|
-
return range.apply(fs, op, expr);
|
|
114
|
-
}
|
|
115
|
-
dateRange(fs, op, expr) {
|
|
116
|
-
const begin = this.getExpression(fs);
|
|
117
|
-
const beginTime = new index_1.ExprTime("date", begin.value, begin.expressionType);
|
|
118
|
-
const endAt = (0, index_1.timeOffset)("date", begin.value, "+", ["1"], this.units);
|
|
119
|
-
const end = new index_1.ExprTime("date", endAt, begin.expressionType);
|
|
120
|
-
const range = new index_1.Range(beginTime, end);
|
|
121
|
-
return range.apply(fs, op, expr);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
exports.ExprGranularTime = ExprGranularTime;
|
|
125
43
|
/**
|
|
126
44
|
* GranularTime made from a literal. Funky because it doesn't know if it
|
|
127
45
|
* is a date or a timestamp in many cases until it is applied.
|
|
128
46
|
*/
|
|
129
|
-
class GranularLiteral extends
|
|
47
|
+
class GranularLiteral extends ast_main_1.ExpressionDef {
|
|
130
48
|
constructor(moment, until, units) {
|
|
131
49
|
super();
|
|
132
50
|
this.moment = moment;
|
|
@@ -207,7 +125,7 @@ class GranularLiteral extends index_1.ExpressionDef {
|
|
|
207
125
|
if (lhs.dataType === "date" && !this.timeType) {
|
|
208
126
|
rangeType = "date";
|
|
209
127
|
}
|
|
210
|
-
const range = new
|
|
128
|
+
const range = new ast_main_1.Range(new ast_main_1.ExprTime(rangeType, (0, time_utils_1.timeLiteral)(this.moment, rangeType, "UTC")), new ast_main_1.ExprTime(rangeType, (0, time_utils_1.timeLiteral)(this.until, rangeType, "UTC")));
|
|
211
129
|
return range.apply(fs, op, left);
|
|
212
130
|
}
|
|
213
131
|
return super.apply(fs, op, left);
|
|
@@ -217,7 +135,7 @@ class GranularLiteral extends index_1.ExpressionDef {
|
|
|
217
135
|
const value = {
|
|
218
136
|
dataType,
|
|
219
137
|
expressionType: "scalar",
|
|
220
|
-
value: (0,
|
|
138
|
+
value: (0, time_utils_1.timeLiteral)(this.moment, dataType, "UTC"),
|
|
221
139
|
};
|
|
222
140
|
// Literals with date resolution can be used as timestamps or dates,
|
|
223
141
|
// this is the third attempt to make that work. It still feels like
|
|
@@ -238,7 +156,7 @@ class GranularLiteral extends index_1.ExpressionDef {
|
|
|
238
156
|
}
|
|
239
157
|
}
|
|
240
158
|
exports.GranularLiteral = GranularLiteral;
|
|
241
|
-
class ExprNow extends
|
|
159
|
+
class ExprNow extends ast_main_1.ExpressionDef {
|
|
242
160
|
constructor() {
|
|
243
161
|
super(...arguments);
|
|
244
162
|
this.elementType = "timestamp";
|
|
@@ -257,93 +175,7 @@ class ExprNow extends index_1.ExpressionDef {
|
|
|
257
175
|
}
|
|
258
176
|
}
|
|
259
177
|
exports.ExprNow = ExprNow;
|
|
260
|
-
class
|
|
261
|
-
constructor(n, timeframe) {
|
|
262
|
-
super({ n });
|
|
263
|
-
this.n = n;
|
|
264
|
-
this.timeframe = timeframe;
|
|
265
|
-
this.elementType = "duration";
|
|
266
|
-
this.legalChildTypes = [index_1.FT.timestampT, index_1.FT.dateT];
|
|
267
|
-
}
|
|
268
|
-
apply(fs, op, left) {
|
|
269
|
-
const lhs = left.getExpression(fs);
|
|
270
|
-
this.typeCheck(this, lhs);
|
|
271
|
-
if ((0, malloy_types_1.isTimeFieldType)(lhs.dataType) && (op === "+" || op === "-")) {
|
|
272
|
-
const num = this.n.getExpression(fs);
|
|
273
|
-
if (!index_1.FT.typeEq(num, index_1.FT.numberT)) {
|
|
274
|
-
this.log(`Duration units needs number not '${num.dataType}`);
|
|
275
|
-
return (0, index_1.errorFor)("illegal unit expression");
|
|
276
|
-
}
|
|
277
|
-
let resultGranularity;
|
|
278
|
-
// Only allow the output of this to be granular if the
|
|
279
|
-
// granularities match, this is still an area where
|
|
280
|
-
// more thought is required.
|
|
281
|
-
if ((0, index_1.isGranularResult)(lhs) && lhs.timeframe == this.timeframe) {
|
|
282
|
-
resultGranularity = lhs.timeframe;
|
|
283
|
-
}
|
|
284
|
-
if (lhs.dataType === "timestamp") {
|
|
285
|
-
const result = (0, index_1.timeOffset)("timestamp", lhs.value, op, num.value, this.timeframe);
|
|
286
|
-
return (0, index_1.timeResult)({
|
|
287
|
-
dataType: "timestamp",
|
|
288
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, num.expressionType),
|
|
289
|
-
value: result,
|
|
290
|
-
}, resultGranularity);
|
|
291
|
-
}
|
|
292
|
-
return (0, index_1.timeResult)({
|
|
293
|
-
dataType: "date",
|
|
294
|
-
expressionType: (0, malloy_types_1.maxExpressionType)(lhs.expressionType, num.expressionType),
|
|
295
|
-
value: (0, index_1.timeOffset)("date", lhs.value, op, num.value, this.timeframe),
|
|
296
|
-
}, resultGranularity);
|
|
297
|
-
}
|
|
298
|
-
return super.apply(fs, op, left);
|
|
299
|
-
}
|
|
300
|
-
getExpression(_fs) {
|
|
301
|
-
return {
|
|
302
|
-
dataType: "duration",
|
|
303
|
-
expressionType: "scalar",
|
|
304
|
-
value: ["__ERROR_DURATION_IS_NOT_A_VALUE__"],
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
exports.ExprDuration = ExprDuration;
|
|
309
|
-
class ExprCompare extends index_1.BinaryBoolean {
|
|
310
|
-
constructor(left, op, right) {
|
|
311
|
-
super(left, op, right);
|
|
312
|
-
this.elementType = "a<=>b";
|
|
313
|
-
this.legalChildTypes = compareTypes[op];
|
|
314
|
-
}
|
|
315
|
-
getExpression(fs) {
|
|
316
|
-
if (!this.right.granular()) {
|
|
317
|
-
const rhs = this.right.requestExpression(fs);
|
|
318
|
-
if (rhs && (0, index_1.isGranularResult)(rhs)) {
|
|
319
|
-
const newRight = new ExprGranularTime(this.right, rhs.timeframe, false);
|
|
320
|
-
return newRight.apply(fs, this.op, this.left);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return this.right.apply(fs, this.op, this.left);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
exports.ExprCompare = ExprCompare;
|
|
327
|
-
class Apply extends ExprCompare {
|
|
328
|
-
constructor(left, right) {
|
|
329
|
-
super(left, "=", right);
|
|
330
|
-
this.left = left;
|
|
331
|
-
this.right = right;
|
|
332
|
-
this.elementType = "apply";
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
exports.Apply = Apply;
|
|
336
|
-
const compareTypes = {
|
|
337
|
-
"~": [index_1.FT.stringT],
|
|
338
|
-
"!~": [index_1.FT.stringT],
|
|
339
|
-
"<": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
340
|
-
"<=": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
341
|
-
"=": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
342
|
-
"!=": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
343
|
-
">=": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
344
|
-
">": [index_1.FT.numberT, index_1.FT.stringT, index_1.FT.dateT, index_1.FT.timestampT],
|
|
345
|
-
};
|
|
346
|
-
class PartialCompare extends index_1.ExpressionDef {
|
|
178
|
+
class PartialCompare extends ast_main_1.ExpressionDef {
|
|
347
179
|
constructor(op, right) {
|
|
348
180
|
super({ right });
|
|
349
181
|
this.op = op;
|
|
@@ -361,7 +193,7 @@ class PartialCompare extends index_1.ExpressionDef {
|
|
|
361
193
|
}
|
|
362
194
|
getExpression(_fs) {
|
|
363
195
|
this.log(`Partial comparison does not have a value`);
|
|
364
|
-
return (0,
|
|
196
|
+
return (0, ast_types_1.errorFor)("no value for partial compare");
|
|
365
197
|
}
|
|
366
198
|
}
|
|
367
199
|
exports.PartialCompare = PartialCompare;
|
|
@@ -369,30 +201,30 @@ exports.PartialCompare = PartialCompare;
|
|
|
369
201
|
* TODO: This is sort of a hand clone of the "Range" class, they should
|
|
370
202
|
* be siblings of a common abstract classs.
|
|
371
203
|
*/
|
|
372
|
-
class ForRange extends
|
|
204
|
+
class ForRange extends ast_main_1.ExpressionDef {
|
|
373
205
|
constructor(from, duration, timeframe) {
|
|
374
206
|
super({ from, duration, timeframe });
|
|
375
207
|
this.from = from;
|
|
376
208
|
this.duration = duration;
|
|
377
209
|
this.timeframe = timeframe;
|
|
378
210
|
this.elementType = "forRange";
|
|
379
|
-
this.legalChildTypes = [
|
|
211
|
+
this.legalChildTypes = [ast_types_1.FT.timestampT, ast_types_1.FT.dateT];
|
|
380
212
|
}
|
|
381
213
|
apply(fs, op, expr) {
|
|
382
214
|
const startV = this.from.getExpression(fs);
|
|
383
215
|
const checkV = expr.getExpression(fs);
|
|
384
216
|
if (!this.typeCheck(expr, checkV)) {
|
|
385
|
-
return (0,
|
|
217
|
+
return (0, ast_types_1.errorFor)("no time for range");
|
|
386
218
|
}
|
|
387
219
|
const nV = this.duration.getExpression(fs);
|
|
388
220
|
if (nV.dataType !== "number") {
|
|
389
221
|
this.log(`FOR duration count must be a number, not '${nV.dataType}'`);
|
|
390
|
-
return (0,
|
|
222
|
+
return (0, ast_types_1.errorFor)("FOR not number");
|
|
391
223
|
}
|
|
392
224
|
const units = this.timeframe.text;
|
|
393
225
|
// If the duration resolution is smaller than date, we have
|
|
394
226
|
// to do the computaion with timestamps.
|
|
395
|
-
const durationRes = (0,
|
|
227
|
+
const durationRes = (0, time_utils_1.resolution)(units);
|
|
396
228
|
let rangeType = durationRes;
|
|
397
229
|
// Next, if the beginning of the range is a timestamp, then we
|
|
398
230
|
// also have to do the computation as a timestamp
|
|
@@ -402,38 +234,38 @@ class ForRange extends index_1.ExpressionDef {
|
|
|
402
234
|
// everything is dates, do date math
|
|
403
235
|
if (checkV.dataType === "date" && rangeType === "date") {
|
|
404
236
|
const rangeStart = this.from;
|
|
405
|
-
const rangeEndV = (0,
|
|
406
|
-
const rangeEnd = new
|
|
407
|
-
return new
|
|
237
|
+
const rangeEndV = (0, time_utils_1.timeOffset)("date", startV.value, "+", nV.value, units);
|
|
238
|
+
const rangeEnd = new ast_main_1.ExprTime("date", rangeEndV);
|
|
239
|
+
return new ast_main_1.Range(rangeStart, rangeEnd).apply(fs, op, expr);
|
|
408
240
|
}
|
|
409
241
|
// Now it doesn't matter if the range is a date or a timestamp,
|
|
410
242
|
// the comparison will be in timestamp space,
|
|
411
|
-
const applyTo =
|
|
243
|
+
const applyTo = ast_main_1.ExprTime.fromValue("timestamp", checkV);
|
|
412
244
|
let rangeStart = this.from;
|
|
413
245
|
let from = startV.value;
|
|
414
246
|
if (startV.dataType === "date") {
|
|
415
247
|
// Time literals with timestamp units can also be used as timestamps;
|
|
416
|
-
const alreadyTs = (0,
|
|
248
|
+
const alreadyTs = (0, ast_types_1.isGranularResult)(startV) && startV.alsoTimestamp;
|
|
417
249
|
if (!alreadyTs) {
|
|
418
250
|
// ... not a literal, need a cast
|
|
419
|
-
from = (0,
|
|
251
|
+
from = (0, time_utils_1.castDateToTimestamp)(from);
|
|
420
252
|
}
|
|
421
|
-
rangeStart = new
|
|
253
|
+
rangeStart = new ast_main_1.ExprTime("timestamp", from, startV.expressionType);
|
|
422
254
|
}
|
|
423
|
-
const to = (0,
|
|
424
|
-
const rangeEnd = new
|
|
425
|
-
return new
|
|
255
|
+
const to = (0, time_utils_1.timeOffset)("timestamp", from, "+", nV.value, units);
|
|
256
|
+
const rangeEnd = new ast_main_1.ExprTime("timestamp", to, startV.expressionType);
|
|
257
|
+
return new ast_main_1.Range(rangeStart, rangeEnd).apply(fs, op, applyTo);
|
|
426
258
|
}
|
|
427
259
|
requestExpression(_fs) {
|
|
428
260
|
return undefined;
|
|
429
261
|
}
|
|
430
262
|
getExpression(_fs) {
|
|
431
263
|
this.log("A Range is not a value");
|
|
432
|
-
return (0,
|
|
264
|
+
return (0, ast_types_1.errorFor)("range has no value");
|
|
433
265
|
}
|
|
434
266
|
}
|
|
435
267
|
exports.ForRange = ForRange;
|
|
436
|
-
class ExprTimeExtract extends
|
|
268
|
+
class ExprTimeExtract extends ast_main_1.ExpressionDef {
|
|
437
269
|
constructor(extractText, args) {
|
|
438
270
|
super({ args });
|
|
439
271
|
this.extractText = extractText;
|
|
@@ -454,23 +286,23 @@ class ExprTimeExtract extends index_1.ExpressionDef {
|
|
|
454
286
|
if (extractTo) {
|
|
455
287
|
if (this.args.length !== 1) {
|
|
456
288
|
this.log(`Extraction function ${extractTo} requires one argument`);
|
|
457
|
-
return (0,
|
|
289
|
+
return (0, ast_types_1.errorFor)(`{this.name} arg count`);
|
|
458
290
|
}
|
|
459
291
|
const from = this.args[0];
|
|
460
|
-
if (from instanceof
|
|
292
|
+
if (from instanceof ast_main_1.Range) {
|
|
461
293
|
const first = from.first.getExpression(fs);
|
|
462
294
|
const last = from.last.getExpression(fs);
|
|
463
295
|
if (!(0, malloy_types_1.isTimeFieldType)(first.dataType)) {
|
|
464
296
|
from.first.log(`Can't extract ${extractTo} from '${first.dataType}'`);
|
|
465
|
-
return (0,
|
|
297
|
+
return (0, ast_types_1.errorFor)(`${extractTo} bad type ${first.dataType}`);
|
|
466
298
|
}
|
|
467
299
|
if (!(0, malloy_types_1.isTimeFieldType)(last.dataType)) {
|
|
468
300
|
from.last.log(`Cannot extract ${extractTo} from '${last.dataType}'`);
|
|
469
|
-
return (0,
|
|
301
|
+
return (0, ast_types_1.errorFor)(`${extractTo} bad type ${last.dataType}`);
|
|
470
302
|
}
|
|
471
303
|
if (!(0, malloy_types_1.isTimestampUnit)(extractTo)) {
|
|
472
304
|
this.log(`Cannot extract ${extractTo} from a range`);
|
|
473
|
-
return (0,
|
|
305
|
+
return (0, ast_types_1.errorFor)(`${extractTo} bad extraction`);
|
|
474
306
|
}
|
|
475
307
|
return {
|
|
476
308
|
dataType: "number",
|
|
@@ -503,7 +335,7 @@ class ExprTimeExtract extends index_1.ExpressionDef {
|
|
|
503
335
|
};
|
|
504
336
|
}
|
|
505
337
|
this.log(`${this.extractText}() requires time type, not '${argV.dataType}'`);
|
|
506
|
-
return (0,
|
|
338
|
+
return (0, ast_types_1.errorFor)(`${this.extractText} bad type ${argV.dataType}`);
|
|
507
339
|
}
|
|
508
340
|
}
|
|
509
341
|
throw this.internalError(`Illegal extraction unit '${this.extractText}'`);
|
|
@@ -520,7 +352,7 @@ ExprTimeExtract.pluralMap = {
|
|
|
520
352
|
minutes: "minute",
|
|
521
353
|
seconds: "second",
|
|
522
354
|
};
|
|
523
|
-
class ExprFunc extends
|
|
355
|
+
class ExprFunc extends ast_main_1.ExpressionDef {
|
|
524
356
|
constructor(name, args) {
|
|
525
357
|
super({ args });
|
|
526
358
|
this.name = name;
|
|
@@ -549,7 +381,7 @@ class ExprFunc extends index_1.ExpressionDef {
|
|
|
549
381
|
return {
|
|
550
382
|
dataType: dataType,
|
|
551
383
|
expressionType,
|
|
552
|
-
value: (0,
|
|
384
|
+
value: (0, ast_types_1.compressExpr)(funcCall),
|
|
553
385
|
};
|
|
554
386
|
}
|
|
555
387
|
}
|