@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.
@@ -1,31 +1,12 @@
1
1
  import { TimestampUnit, ExtractUnit, TimeFieldType } from "../../model/malloy_types";
2
2
  import { FieldSpace } from "../field-space";
3
- import { ExpressionDef, BinaryBoolean, ExprValue, MalloyElement, Comparison } from "./index";
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.Apply = exports.ExprCompare = exports.ExprDuration = exports.ExprNow = exports.GranularLiteral = exports.ExprGranularTime = exports.Timeframe = void 0;
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 index_1 = require("./index");
29
- class Timeframe extends index_1.MalloyElement {
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 index_1.ExpressionDef {
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 index_1.Range(new index_1.ExprTime(rangeType, (0, index_1.timeLiteral)(this.moment, rangeType, "UTC")), new index_1.ExprTime(rangeType, (0, index_1.timeLiteral)(this.until, rangeType, "UTC")));
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, index_1.timeLiteral)(this.moment, dataType, "UTC"),
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 index_1.ExpressionDef {
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 ExprDuration extends index_1.ExpressionDef {
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, index_1.errorFor)("no value for partial compare");
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 index_1.ExpressionDef {
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 = [index_1.FT.timestampT, index_1.FT.dateT];
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, index_1.errorFor)("no time for range");
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, index_1.errorFor)("FOR not number");
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, index_1.resolution)(units);
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, index_1.timeOffset)("date", startV.value, "+", nV.value, units);
406
- const rangeEnd = new index_1.ExprTime("date", rangeEndV);
407
- return new index_1.Range(rangeStart, rangeEnd).apply(fs, op, expr);
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 = index_1.ExprTime.fromValue("timestamp", checkV);
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, index_1.isGranularResult)(startV) && startV.alsoTimestamp;
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, index_1.castDateToTimestamp)(from);
251
+ from = (0, time_utils_1.castDateToTimestamp)(from);
420
252
  }
421
- rangeStart = new index_1.ExprTime("timestamp", from, startV.expressionType);
253
+ rangeStart = new ast_main_1.ExprTime("timestamp", from, startV.expressionType);
422
254
  }
423
- const to = (0, index_1.timeOffset)("timestamp", from, "+", nV.value, units);
424
- const rangeEnd = new index_1.ExprTime("timestamp", to, startV.expressionType);
425
- return new index_1.Range(rangeStart, rangeEnd).apply(fs, op, applyTo);
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, index_1.errorFor)("range has no value");
264
+ return (0, ast_types_1.errorFor)("range has no value");
433
265
  }
434
266
  }
435
267
  exports.ForRange = ForRange;
436
- class ExprTimeExtract extends index_1.ExpressionDef {
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, index_1.errorFor)(`{this.name} arg count`);
289
+ return (0, ast_types_1.errorFor)(`{this.name} arg count`);
458
290
  }
459
291
  const from = this.args[0];
460
- if (from instanceof index_1.Range) {
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, index_1.errorFor)(`${extractTo} bad type ${first.dataType}`);
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, index_1.errorFor)(`${extractTo} bad type ${last.dataType}`);
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, index_1.errorFor)(`${extractTo} bad extraction`);
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, index_1.errorFor)(`${this.extractText} bad type ${argV.dataType}`);
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 index_1.ExpressionDef {
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, index_1.compressExpr)(funcCall),
384
+ value: (0, ast_types_1.compressExpr)(funcCall),
553
385
  };
554
386
  }
555
387
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.22-dev230117232218",
3
+ "version": "0.0.22-dev230119001546",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",