@malloydata/malloy 0.0.24-dev230302224355 → 0.0.24-dev230306192917

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.
@@ -2,10 +2,6 @@ import { ExprValue } from '../types/expr-value';
2
2
  import { ExpressionDef } from '../types/expression-def';
3
3
  import { FieldSpace } from '../types/field-space';
4
4
  import { Timeframe } from './time-frame';
5
- /**
6
- * TODO: This is sort of a hand clone of the "Range" class, they should
7
- * be siblings of a common abstract classs.
8
- */
9
5
  export declare class ForRange extends ExpressionDef {
10
6
  readonly from: ExpressionDef;
11
7
  readonly duration: ExpressionDef;
@@ -14,6 +10,6 @@ export declare class ForRange extends ExpressionDef {
14
10
  legalChildTypes: import("../types/type-desc").TypeDesc[];
15
11
  constructor(from: ExpressionDef, duration: ExpressionDef, timeframe: Timeframe);
16
12
  apply(fs: FieldSpace, op: string, expr: ExpressionDef): ExprValue;
17
- requestExpression(_fs: FieldSpace): ExprValue | undefined;
13
+ requestExpression(_fs: FieldSpace): undefined;
18
14
  getExpression(_fs: FieldSpace): ExprValue;
19
15
  }
@@ -27,13 +27,8 @@ const ast_utils_1 = require("../ast-utils");
27
27
  const fragtype_utils_1 = require("../fragtype-utils");
28
28
  const time_utils_1 = require("../time-utils");
29
29
  const expression_def_1 = require("../types/expression-def");
30
- const granular_result_1 = require("../types/granular-result");
31
30
  const expr_time_1 = require("./expr-time");
32
31
  const range_1 = require("./range");
33
- /**
34
- * TODO: This is sort of a hand clone of the "Range" class, they should
35
- * be siblings of a common abstract classs.
36
- */
37
32
  class ForRange extends expression_def_1.ExpressionDef {
38
33
  constructor(from, duration, timeframe) {
39
34
  super({ from: from, duration: duration, timeframe: timeframe });
@@ -57,8 +52,7 @@ class ForRange extends expression_def_1.ExpressionDef {
57
52
  const units = this.timeframe.text;
58
53
  // If the duration resolution is smaller than date, we have
59
54
  // to do the computaion with timestamps.
60
- const durationRes = (0, time_utils_1.resolution)(units);
61
- let rangeType = durationRes;
55
+ let rangeType = (0, time_utils_1.resolution)(units);
62
56
  // Next, if the beginning of the range is a timestamp, then we
63
57
  // also have to do the computation as a timestamp
64
58
  if (startV.dataType === 'timestamp') {
@@ -77,10 +71,11 @@ class ForRange extends expression_def_1.ExpressionDef {
77
71
  let rangeStart = this.from;
78
72
  let from = startV.value;
79
73
  if (startV.dataType === 'date') {
80
- // Time literals with timestamp units can also be used as timestamps;
81
- const alreadyTs = (0, granular_result_1.isGranularResult)(startV) && startV.alsoTimestamp;
82
- if (!alreadyTs) {
83
- // ... not a literal, need a cast
74
+ const tsVersion = startV.morphic && startV.morphic['timestamp'];
75
+ if (tsVersion) {
76
+ from = tsVersion;
77
+ }
78
+ else {
84
79
  from = (0, time_utils_1.castDateToTimestamp)(from);
85
80
  }
86
81
  rangeStart = new expr_time_1.ExprTime('timestamp', from, startV.expressionType);
@@ -7,6 +7,6 @@ export declare class Range extends ExpressionDef {
7
7
  elementType: string;
8
8
  constructor(first: ExpressionDef, last: ExpressionDef);
9
9
  apply(fs: FieldSpace, op: string, expr: ExpressionDef): ExprValue;
10
- requestExpression(_fs: FieldSpace): ExprValue | undefined;
10
+ requestExpression(_fs: FieldSpace): undefined;
11
11
  getExpression(_fs: FieldSpace): ExprValue;
12
12
  }
@@ -73,6 +73,7 @@ class Range extends expression_def_1.ExpressionDef {
73
73
  return undefined;
74
74
  }
75
75
  getExpression(_fs) {
76
+ this.log('A Range is not a value');
76
77
  return (0, ast_utils_1.errorFor)('a range is not a value');
77
78
  }
78
79
  }
@@ -0,0 +1,77 @@
1
+ import { TimeFieldType, TimestampUnit, TimeLiteralFragment } from '../../../model/malloy_types';
2
+ import { ExprValue } from '../types/expr-value';
3
+ import { FieldSpace } from '../types/field-space';
4
+ import { ExpressionDef } from '../types/expression-def';
5
+ import { TimeResult } from '../types/time-result';
6
+ export declare class TimeFormatError extends Error {
7
+ }
8
+ interface TimeText {
9
+ text: string;
10
+ tzSpec?: string;
11
+ isLocale?: boolean;
12
+ }
13
+ /**
14
+ * Literals specified with an @ in Malloy all become one of these
15
+ */
16
+ declare abstract class TimeLiteral extends ExpressionDef {
17
+ readonly units: TimestampUnit | undefined;
18
+ readonly timeType: TimeFieldType;
19
+ literalPart: string;
20
+ nextLit?: string;
21
+ timeZone?: string;
22
+ isLocale?: boolean;
23
+ constructor(tm: TimeText, units: TimestampUnit | undefined, timeType: TimeFieldType);
24
+ protected getLiteral(): TimeLiteralFragment;
25
+ protected getValue(): TimeResult;
26
+ getExpression(_fs: FieldSpace): ExprValue;
27
+ apply(fs: FieldSpace, op: string, left: ExpressionDef): ExprValue;
28
+ granular(): boolean;
29
+ }
30
+ export declare class LiteralTimestamp extends TimeLiteral {
31
+ elementType: string;
32
+ constructor(tm: TimeText, units?: TimestampUnit);
33
+ static parse(literalTs: string): LiteralTimestamp | undefined;
34
+ }
35
+ /**
36
+ * Granular literals imply a range. The end of that range is a constant
37
+ * in the generated expression, computed at compile time, to make filters faster.
38
+ */
39
+ declare abstract class GranularLiteral extends TimeLiteral {
40
+ readonly nextLit: string;
41
+ constructor(tm: TimeText, units: TimestampUnit | undefined, timeType: TimeFieldType, nextLit: string);
42
+ }
43
+ export declare class LiteralHour extends GranularLiteral {
44
+ elementType: string;
45
+ constructor(tm: TimeText, next: string);
46
+ static parse(literalTs: string): LiteralHour | undefined;
47
+ }
48
+ declare abstract class DateBasedLiteral extends GranularLiteral {
49
+ constructor(tm: TimeText, units: TimestampUnit, nextLit: string);
50
+ getExpression(_fs: FieldSpace): ExprValue;
51
+ }
52
+ export declare class LiteralDay extends DateBasedLiteral {
53
+ elementType: string;
54
+ constructor(tm: TimeText, next: string);
55
+ static parse(literalTs: string): LiteralDay | undefined;
56
+ }
57
+ export declare class LiteralWeek extends DateBasedLiteral {
58
+ elementType: string;
59
+ constructor(tm: TimeText, next: string);
60
+ static parse(literalTs: string): LiteralWeek | undefined;
61
+ }
62
+ export declare class LiteralMonth extends DateBasedLiteral {
63
+ elementType: string;
64
+ constructor(tm: TimeText, next: string);
65
+ static parse(literalTs: string): LiteralMonth | undefined;
66
+ }
67
+ export declare class LiteralQuarter extends DateBasedLiteral {
68
+ elementType: string;
69
+ constructor(tm: TimeText, next: string);
70
+ static parse(literalTs: string): LiteralQuarter | undefined;
71
+ }
72
+ export declare class LiteralYear extends DateBasedLiteral {
73
+ elementType: string;
74
+ constructor(tm: TimeText, next: string);
75
+ static parse(literalTs: string): LiteralYear | undefined;
76
+ }
77
+ export {};
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2023 Google LLC
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files
7
+ * (the "Software"), to deal in the Software without restriction,
8
+ * including without limitation the rights to use, copy, modify, merge,
9
+ * publish, distribute, sublicense, and/or sell copies of the Software,
10
+ * and to permit persons to whom the Software is furnished to do so,
11
+ * subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.LiteralYear = exports.LiteralQuarter = exports.LiteralMonth = exports.LiteralWeek = exports.LiteralDay = exports.LiteralHour = exports.LiteralTimestamp = exports.TimeFormatError = void 0;
26
+ const luxon_1 = require("luxon");
27
+ const malloy_types_1 = require("../../../model/malloy_types");
28
+ const range_1 = require("./range");
29
+ const expr_time_1 = require("./expr-time");
30
+ const expression_def_1 = require("../types/expression-def");
31
+ class TimeFormatError extends Error {
32
+ }
33
+ exports.TimeFormatError = TimeFormatError;
34
+ /**
35
+ * Finds and seperates out an optional timezone description from a time literal
36
+ * @param literal legal Malloy timestamp literal string
37
+ */
38
+ function preParse(literal, checkTz) {
39
+ const text = literal.slice(1); // Drop the '@'
40
+ if (checkTz) {
41
+ const hasLocale = text.match(/\[[^\]]+]$/);
42
+ if (hasLocale) {
43
+ const tzSpec = hasLocale[0].slice(1, -1);
44
+ return {
45
+ tzSpec,
46
+ text: text.slice(0, -hasLocale[0].length),
47
+ isLocale: true,
48
+ };
49
+ }
50
+ const hasOffsetTz = text.match(/[+-]\d+(:\d+)?$/);
51
+ if (hasOffsetTz) {
52
+ const tzSpec = hasOffsetTz[0];
53
+ return { tzSpec, text: text.slice(0, -tzSpec.length) };
54
+ }
55
+ }
56
+ return { text };
57
+ }
58
+ const fYear = 'yyyy';
59
+ const fMonth = `${fYear}-LL`;
60
+ const fDay = `${fMonth}-dd`;
61
+ const fHour = `${fDay} HH`;
62
+ const fMinute = `${fHour}:mm`;
63
+ const fTimestamp = `${fMinute}:ss`;
64
+ /**
65
+ * Literals specified with an @ in Malloy all become one of these
66
+ */
67
+ class TimeLiteral extends expression_def_1.ExpressionDef {
68
+ constructor(tm, units, timeType) {
69
+ super();
70
+ this.units = units;
71
+ this.timeType = timeType;
72
+ this.literalPart = tm.text;
73
+ if (tm.tzSpec) {
74
+ this.timeZone = tm.tzSpec;
75
+ if (tm.isLocale) {
76
+ this.isLocale = true;
77
+ }
78
+ }
79
+ }
80
+ getLiteral() {
81
+ return {
82
+ type: 'dialect',
83
+ function: 'timeLiteral',
84
+ literal: this.literalPart,
85
+ literalType: this.timeType,
86
+ timezone: this.timeZone || 'UTC',
87
+ tzIsLocale: this.isLocale,
88
+ };
89
+ }
90
+ getValue() {
91
+ const timeFrag = this.getLiteral();
92
+ const dataType = timeFrag.literalType;
93
+ const expressionType = 'scalar';
94
+ const value = [timeFrag];
95
+ if (this.units) {
96
+ return { dataType, expressionType, value, timeframe: this.units };
97
+ }
98
+ return { dataType, expressionType, value };
99
+ }
100
+ getExpression(_fs) {
101
+ return this.getValue();
102
+ }
103
+ apply(fs, op, left) {
104
+ if (this.nextLit) {
105
+ // We have a chance to write our own range comparison will all constants.
106
+ const lhs = left.getExpression(fs);
107
+ // MTOY todo ... only apply range on ? maybe
108
+ if ((0, malloy_types_1.isTimeFieldType)(lhs.dataType)) {
109
+ let rangeType = 'timestamp';
110
+ if (lhs.dataType === 'date' && !this.timeType) {
111
+ rangeType = 'date';
112
+ }
113
+ const rangeStart = this.getLiteral();
114
+ const rangeEnd = { ...rangeStart, literal: this.nextLit };
115
+ const range = new range_1.Range(new expr_time_1.ExprTime(rangeType, [rangeStart]), new expr_time_1.ExprTime(rangeType, [rangeEnd]));
116
+ return range.apply(fs, op, left);
117
+ }
118
+ }
119
+ return super.apply(fs, op, left);
120
+ }
121
+ granular() {
122
+ return this.nextLit !== undefined;
123
+ }
124
+ }
125
+ class LiteralTimestamp extends TimeLiteral {
126
+ constructor(tm, units) {
127
+ super(tm, units, 'timestamp');
128
+ this.elementType = 'literal:timestamp';
129
+ }
130
+ static parse(literalTs) {
131
+ // let subSecs: string | undefined;
132
+ let validParse = false;
133
+ let units = undefined;
134
+ let next = undefined;
135
+ const tm = preParse(literalTs, true);
136
+ literalTs = tm.text;
137
+ if (literalTs[10] === 'T') {
138
+ literalTs = literalTs.slice(0, 10) + ' ' + literalTs.slice(11);
139
+ tm.text = literalTs;
140
+ }
141
+ const hasSubsecs = literalTs.match(/^([^.,]+)[,.](\d+)$/);
142
+ if (hasSubsecs) {
143
+ literalTs = hasSubsecs[1];
144
+ // subSecs = hasSubsecs[2];
145
+ // TODO mtoy subsecond units not ignored
146
+ }
147
+ const tss = luxon_1.DateTime.fromFormat(literalTs, fTimestamp);
148
+ if (tss.isValid) {
149
+ validParse = true;
150
+ }
151
+ else {
152
+ const tsm = luxon_1.DateTime.fromFormat(literalTs, fMinute);
153
+ if (tsm.isValid) {
154
+ validParse = true;
155
+ tm.text = tm.text + ':00';
156
+ units = 'minute';
157
+ next = tss.plus({ minute: 1 }).toFormat(fTimestamp);
158
+ // MTOY todo minutes should be granular
159
+ }
160
+ }
161
+ if (validParse) {
162
+ const ts = new LiteralTimestamp(tm, units);
163
+ if (next) {
164
+ ts.nextLit = next;
165
+ }
166
+ return ts;
167
+ }
168
+ return undefined;
169
+ }
170
+ }
171
+ exports.LiteralTimestamp = LiteralTimestamp;
172
+ /**
173
+ * Granular literals imply a range. The end of that range is a constant
174
+ * in the generated expression, computed at compile time, to make filters faster.
175
+ */
176
+ class GranularLiteral extends TimeLiteral {
177
+ constructor(tm, units, timeType, nextLit) {
178
+ super(tm, units, timeType);
179
+ this.nextLit = nextLit;
180
+ }
181
+ }
182
+ // MTOY todo should probably put the time zone information into the luxon object
183
+ // so that "adding an hour just before DST" works properly when a locale based
184
+ // time is specified, but then that introduces the possibility that a locale
185
+ // is defined differently in the DB than in Luxon ... which i don't have
186
+ // the brain space to think about right now
187
+ class LiteralHour extends GranularLiteral {
188
+ constructor(tm, next) {
189
+ super(tm, 'hour', 'timestamp', next);
190
+ this.elementType = 'literal:hour';
191
+ }
192
+ static parse(literalTs) {
193
+ const tm = preParse(literalTs, false);
194
+ let nextHour = tm.text;
195
+ const hourParse = luxon_1.DateTime.fromFormat(tm.text, fHour);
196
+ if (hourParse.isValid) {
197
+ tm.text = tm.text + ':00:00';
198
+ nextHour = hourParse.plus({ hour: 1 }).toFormat(fTimestamp);
199
+ return new LiteralHour(tm, nextHour);
200
+ }
201
+ }
202
+ }
203
+ exports.LiteralHour = LiteralHour;
204
+ class DateBasedLiteral extends GranularLiteral {
205
+ constructor(tm, units, nextLit) {
206
+ super(tm, units, 'date', nextLit);
207
+ }
208
+ getExpression(_fs) {
209
+ const morphicValue = this.getValue();
210
+ const tsLiteral = this.getLiteral();
211
+ tsLiteral.literalType = 'timestamp';
212
+ tsLiteral.literal = tsLiteral.literal + ' 00:00:00';
213
+ morphicValue.morphic = { timestamp: [tsLiteral] };
214
+ return morphicValue;
215
+ }
216
+ }
217
+ class LiteralDay extends DateBasedLiteral {
218
+ constructor(tm, next) {
219
+ super(tm, 'day', next);
220
+ this.elementType = 'literal:day';
221
+ }
222
+ static parse(literalTs) {
223
+ const tm = preParse(literalTs, false);
224
+ let nextDay = tm.text;
225
+ const dayParse = luxon_1.DateTime.fromFormat(tm.text, fDay);
226
+ if (dayParse.isValid) {
227
+ nextDay = dayParse.plus({ day: 1 }).toFormat(fTimestamp);
228
+ return new LiteralDay(tm, nextDay);
229
+ }
230
+ }
231
+ }
232
+ exports.LiteralDay = LiteralDay;
233
+ class LiteralWeek extends DateBasedLiteral {
234
+ constructor(tm, next) {
235
+ super(tm, 'week', next);
236
+ this.elementType = 'literal:week';
237
+ }
238
+ static parse(literalTs) {
239
+ const tm = preParse(literalTs, false);
240
+ let nextWeek = tm.text;
241
+ const datePart = tm.text.slice(0, 10);
242
+ const yyyymmdd = luxon_1.DateTime.fromFormat(datePart, fDay);
243
+ if (yyyymmdd.isValid) {
244
+ // wonky because luxon uses monday weeks and bigquery uses sunday weeks
245
+ let sunday = yyyymmdd;
246
+ if (yyyymmdd.weekday !== 7) {
247
+ sunday = yyyymmdd.startOf('week').minus({ day: 1 });
248
+ }
249
+ const next = sunday.plus({ days: 7 });
250
+ tm.text = sunday.toFormat(fDay);
251
+ nextWeek = next.toFormat(fDay);
252
+ return new LiteralWeek(tm, nextWeek);
253
+ }
254
+ }
255
+ }
256
+ exports.LiteralWeek = LiteralWeek;
257
+ class LiteralMonth extends DateBasedLiteral {
258
+ constructor(tm, next) {
259
+ super(tm, 'month', next);
260
+ this.elementType = 'literal:month';
261
+ }
262
+ static parse(literalTs) {
263
+ const tm = preParse(literalTs, false);
264
+ let nextMonth = tm.text;
265
+ const yyyymm = luxon_1.DateTime.fromFormat(tm.text, fMonth);
266
+ if (yyyymm.isValid) {
267
+ const next = yyyymm.plus({ months: 1 });
268
+ tm.text = yyyymm.toFormat(fDay);
269
+ nextMonth = next.toFormat(fDay);
270
+ return new LiteralMonth(tm, nextMonth);
271
+ }
272
+ }
273
+ }
274
+ exports.LiteralMonth = LiteralMonth;
275
+ class LiteralQuarter extends DateBasedLiteral {
276
+ constructor(tm, next) {
277
+ super(tm, 'quarter', next);
278
+ this.elementType = 'literal:quarter';
279
+ }
280
+ static parse(literalTs) {
281
+ const tm = preParse(literalTs, false);
282
+ let nextQuarter = tm.text;
283
+ const quarter = tm.text.match(/(^\d{4})-[qQ](\d)$/);
284
+ if (quarter) {
285
+ const qplus = Number.parseInt(quarter[2]) - 1;
286
+ let qstart = luxon_1.DateTime.fromFormat(quarter[1], 'yyyy');
287
+ if (qplus > 0) {
288
+ qstart = qstart.plus({ quarters: qplus });
289
+ }
290
+ const qend = qstart.plus({ quarter: 1 });
291
+ tm.text = qstart.toFormat(fDay);
292
+ nextQuarter = qend.toFormat(fDay);
293
+ return new LiteralQuarter(tm, nextQuarter);
294
+ }
295
+ }
296
+ }
297
+ exports.LiteralQuarter = LiteralQuarter;
298
+ class LiteralYear extends DateBasedLiteral {
299
+ constructor(tm, next) {
300
+ super(tm, 'year', next);
301
+ this.elementType = 'literal:year';
302
+ }
303
+ static parse(literalTs) {
304
+ const tm = preParse(literalTs, false);
305
+ let next = tm.text;
306
+ const yyyy = luxon_1.DateTime.fromFormat(tm.text, fYear);
307
+ if (yyyy.isValid) {
308
+ const nextYear = yyyy.plus({ year: 1 });
309
+ tm.text = yyyy.toFormat(fDay);
310
+ next = nextYear.toFormat(fDay);
311
+ return new LiteralYear(tm, next);
312
+ }
313
+ }
314
+ }
315
+ exports.LiteralYear = LiteralYear;
316
+ //# sourceMappingURL=time-literal.js.map
@@ -39,7 +39,7 @@ export * from './expressions/expr-sum';
39
39
  export * from './expressions/expr-time-extract';
40
40
  export * from './expressions/expr-ungroup';
41
41
  export * from './expressions/for-range';
42
- export * from './expressions/granular-literal';
42
+ export * from './expressions/time-literal';
43
43
  export * from './expressions/partial-compare';
44
44
  export * from './expressions/pick-when';
45
45
  export * from './expressions/range';
@@ -77,7 +77,7 @@ __exportStar(require("./expressions/expr-sum"), exports);
77
77
  __exportStar(require("./expressions/expr-time-extract"), exports);
78
78
  __exportStar(require("./expressions/expr-ungroup"), exports);
79
79
  __exportStar(require("./expressions/for-range"), exports);
80
- __exportStar(require("./expressions/granular-literal"), exports);
80
+ __exportStar(require("./expressions/time-literal"), exports);
81
81
  __exportStar(require("./expressions/partial-compare"), exports);
82
82
  __exportStar(require("./expressions/pick-when"), exports);
83
83
  __exportStar(require("./expressions/range"), exports);
@@ -1,12 +1,10 @@
1
1
  import { AtomicFieldType, Expr, Fragment, TimeFieldType, TimestampUnit } from '../../model/malloy_types';
2
- import { GranularResult } from './types/granular-result';
3
2
  import { TimeResult } from './types/time-result';
4
3
  export declare function timeOffset(timeType: TimeFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit): Expr;
5
4
  export declare function castTo(castType: AtomicFieldType, from: Expr, safe?: boolean): Expr;
6
5
  export declare function castTimestampToDate(from: Expr, safe?: boolean): Expr;
7
6
  export declare function castDateToTimestamp(from: Expr, safe?: boolean): Expr;
8
7
  export declare function resolution(timeframe: string): TimeFieldType;
9
- export declare function timeResult(t: TimeResult, tt: TimestampUnit | undefined): TimeResult | GranularResult;
10
- export declare function timeLiteral(literalStr: string, timeType: TimeFieldType, tz: string): Expr;
8
+ export declare function timeResult(t: TimeResult, tt: TimestampUnit | undefined): TimeResult;
11
9
  export declare function timestampOffset(from: Fragment[], op: '+' | '-', n: Fragment[], timeframe: TimestampUnit, fromNotTimestamp?: boolean): Fragment[];
12
10
  export declare function dateOffset(from: Fragment[], op: '+' | '-', n: Fragment[], timeframe: TimestampUnit): Fragment[];
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.dateOffset = exports.timestampOffset = exports.timeLiteral = exports.timeResult = exports.resolution = exports.castDateToTimestamp = exports.castTimestampToDate = exports.castTo = exports.timeOffset = void 0;
25
+ exports.dateOffset = exports.timestampOffset = exports.timeResult = exports.resolution = exports.castDateToTimestamp = exports.castTimestampToDate = exports.castTo = exports.timeOffset = void 0;
26
26
  const utils_1 = require("./expressions/utils");
27
27
  function timeOffset(timeType, from, op, n, timeframe) {
28
28
  return [
@@ -91,17 +91,6 @@ function timeResult(t, tt) {
91
91
  return t;
92
92
  }
93
93
  exports.timeResult = timeResult;
94
- function timeLiteral(literalStr, timeType, tz) {
95
- const fragment = {
96
- type: 'dialect',
97
- function: 'timeLiteral',
98
- literal: literalStr,
99
- literalType: timeType,
100
- timezone: tz,
101
- };
102
- return [fragment];
103
- }
104
- exports.timeLiteral = timeLiteral;
105
94
  function timestampOffset(from, op, n, timeframe, fromNotTimestamp = false) {
106
95
  const useDatetime = ['week', 'month', 'quarter', 'year'].includes(timeframe);
107
96
  const add = op === '+' ? '_ADD' : '_SUB';
@@ -1,5 +1,8 @@
1
1
  import { Fragment } from '../../../model/malloy_types';
2
2
  import { TypeDesc } from './type-desc';
3
+ declare type MorphicValues = Record<string, Fragment[]>;
3
4
  export interface ExprResult extends TypeDesc {
4
5
  value: Fragment[];
6
+ morphic?: MorphicValues;
5
7
  }
8
+ export {};
@@ -1,3 +1,3 @@
1
- import { GranularResult } from './granular-result';
2
1
  import { ExprResult } from './expr-result';
3
- export declare type ExprValue = ExprResult | GranularResult;
2
+ import { TimeResult } from './time-result';
3
+ export declare type ExprValue = ExprResult | TimeResult;
@@ -24,10 +24,10 @@
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.isGranularResult = void 0;
26
26
  function isGranularResult(v) {
27
- if (v.dataType !== 'date' && v.dataType !== 'timestamp') {
28
- return false;
27
+ if (v.dataType === 'date' || v.dataType === 'timestamp') {
28
+ return v.timeframe !== undefined;
29
29
  }
30
- return v.timeframe !== undefined;
30
+ return false;
31
31
  }
32
32
  exports.isGranularResult = isGranularResult;
33
33
  //# sourceMappingURL=granular-result.js.map
@@ -1,6 +1,6 @@
1
- import { TimeFieldType } from '../../../model/malloy_types';
1
+ import { TimeFieldType, TimestampUnit } from '../../../model/malloy_types';
2
2
  import { ExprResult } from './expr-result';
3
3
  export interface TimeResult extends ExprResult {
4
4
  dataType: TimeFieldType;
5
- alsoTimestamp?: true;
5
+ timeframe?: TimestampUnit;
6
6
  }
@@ -121,25 +121,26 @@ export declare class MalloyLexer extends Lexer {
121
121
  static readonly MATCH = 116;
122
122
  static readonly PERCENT = 117;
123
123
  static readonly LITERAL_TIMESTAMP = 118;
124
- static readonly LITERAL_DAY = 119;
125
- static readonly LITERAL_QUARTER = 120;
126
- static readonly LITERAL_MONTH = 121;
127
- static readonly LITERAL_WEEK = 122;
128
- static readonly LITERAL_YEAR = 123;
129
- static readonly IDENTIFIER = 124;
130
- static readonly PERCENT_LITERAL = 125;
131
- static readonly INTEGER_LITERAL = 126;
132
- static readonly NUMERIC_LITERAL = 127;
133
- static readonly OBJECT_NAME_LITERAL = 128;
134
- static readonly BLOCK_COMMENT = 129;
135
- static readonly COMMENT_TO_EOL = 130;
136
- static readonly WHITE_SPACE = 131;
137
- static readonly SQL_BEGIN = 132;
138
- static readonly CLOSE_CODE = 133;
139
- static readonly UNWATED_CHARS_TRAILING_NUMBERS = 134;
140
- static readonly UNEXPECTED_CHAR = 135;
141
- static readonly OPEN_CODE = 136;
142
- static readonly SQL_END = 137;
124
+ static readonly LITERAL_HOUR = 119;
125
+ static readonly LITERAL_DAY = 120;
126
+ static readonly LITERAL_QUARTER = 121;
127
+ static readonly LITERAL_MONTH = 122;
128
+ static readonly LITERAL_WEEK = 123;
129
+ static readonly LITERAL_YEAR = 124;
130
+ static readonly IDENTIFIER = 125;
131
+ static readonly PERCENT_LITERAL = 126;
132
+ static readonly INTEGER_LITERAL = 127;
133
+ static readonly NUMERIC_LITERAL = 128;
134
+ static readonly OBJECT_NAME_LITERAL = 129;
135
+ static readonly BLOCK_COMMENT = 130;
136
+ static readonly COMMENT_TO_EOL = 131;
137
+ static readonly WHITE_SPACE = 132;
138
+ static readonly SQL_BEGIN = 133;
139
+ static readonly CLOSE_CODE = 134;
140
+ static readonly UNWATED_CHARS_TRAILING_NUMBERS = 135;
141
+ static readonly UNEXPECTED_CHAR = 136;
142
+ static readonly OPEN_CODE = 137;
143
+ static readonly SQL_END = 138;
143
144
  static readonly SQL_MODE = 1;
144
145
  static readonly channelNames: string[];
145
146
  static readonly modeNames: string[];