@malloydata/malloy 0.0.205-dev241028163321 → 0.0.205-dev241028192658
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/dialect/functions/util.d.ts +16 -16
- package/dist/dialect/functions/util.js +16 -48
- package/dist/index.d.ts +1 -1
- package/dist/lang/ast/ast-utils.js +1 -1
- package/dist/lang/ast/expressions/binary-boolean.js +27 -4
- package/dist/lang/ast/expressions/binary-numeric.js +25 -2
- package/dist/lang/ast/expressions/boolean.js +25 -2
- package/dist/lang/ast/expressions/case.js +41 -20
- package/dist/lang/ast/expressions/expr-aggregate-function.d.ts +2 -2
- package/dist/lang/ast/expressions/expr-aggregate-function.js +30 -10
- package/dist/lang/ast/expressions/expr-alternation-tree.js +2 -2
- package/dist/lang/ast/expressions/expr-asymmetric.d.ts +2 -0
- package/dist/lang/ast/expressions/expr-asymmetric.js +3 -0
- package/dist/lang/ast/expressions/expr-cast.js +4 -6
- package/dist/lang/ast/expressions/expr-coalesce.js +30 -7
- package/dist/lang/ast/expressions/expr-compare.js +33 -10
- package/dist/lang/ast/expressions/expr-count-distinct.d.ts +2 -0
- package/dist/lang/ast/expressions/expr-count-distinct.js +34 -2
- package/dist/lang/ast/expressions/expr-count.d.ts +1 -0
- package/dist/lang/ast/expressions/expr-count.js +11 -1
- package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-func.js +41 -15
- package/dist/lang/ast/expressions/expr-granular-time.js +36 -14
- package/dist/lang/ast/expressions/expr-logical-op.js +25 -2
- package/dist/lang/ast/expressions/expr-max.d.ts +3 -4
- package/dist/lang/ast/expressions/expr-max.js +27 -4
- package/dist/lang/ast/expressions/expr-min.d.ts +3 -4
- package/dist/lang/ast/expressions/expr-min.js +27 -4
- package/dist/lang/ast/expressions/expr-minus.js +27 -4
- package/dist/lang/ast/expressions/expr-not.js +26 -3
- package/dist/lang/ast/expressions/expr-now.js +1 -1
- package/dist/lang/ast/expressions/expr-null.js +1 -1
- package/dist/lang/ast/expressions/expr-number.js +5 -1
- package/dist/lang/ast/expressions/expr-props.js +25 -2
- package/dist/lang/ast/expressions/expr-regex.js +1 -1
- package/dist/lang/ast/expressions/expr-string.js +1 -1
- package/dist/lang/ast/expressions/expr-time-extract.js +18 -18
- package/dist/lang/ast/expressions/expr-time.js +4 -4
- package/dist/lang/ast/expressions/expr-ungroup.d.ts +0 -2
- package/dist/lang/ast/expressions/expr-ungroup.js +26 -6
- package/dist/lang/ast/expressions/for-range.js +32 -9
- package/dist/lang/ast/expressions/pick-when.js +46 -25
- package/dist/lang/ast/expressions/range.js +1 -1
- package/dist/lang/ast/expressions/time-literal.js +9 -4
- package/dist/lang/ast/field-space/index-field-space.js +1 -3
- package/dist/lang/ast/field-space/project-field-space.d.ts +1 -1
- package/dist/lang/ast/field-space/project-field-space.js +2 -1
- package/dist/lang/ast/field-space/query-spaces.d.ts +1 -1
- package/dist/lang/ast/field-space/query-spaces.js +4 -3
- package/dist/lang/ast/field-space/reference-field.js +43 -10
- package/dist/lang/ast/field-space/rename-space-field.d.ts +2 -2
- package/dist/lang/ast/field-space/static-space.js +1 -1
- package/dist/lang/ast/field-space/struct-space-field-base.d.ts +2 -2
- package/dist/lang/ast/field-space/struct-space-field-base.js +40 -8
- package/dist/lang/ast/field-space/view-field.d.ts +2 -2
- package/dist/lang/ast/field-space/view-field.js +25 -1
- package/dist/lang/ast/parameters/has-parameter.d.ts +1 -1
- package/dist/lang/ast/parameters/has-parameter.js +8 -8
- package/dist/lang/ast/query-items/field-declaration.d.ts +2 -1
- package/dist/lang/ast/query-items/field-declaration.js +34 -9
- package/dist/lang/ast/query-items/typecheck_utils.js +11 -13
- package/dist/lang/ast/query-properties/filters.js +1 -1
- package/dist/lang/ast/source-elements/named-source.js +2 -2
- package/dist/lang/ast/source-properties/join.js +3 -3
- package/dist/lang/ast/time-utils.d.ts +2 -2
- package/dist/lang/ast/time-utils.js +6 -1
- package/dist/lang/ast/typedesc-utils.d.ts +48 -0
- package/dist/lang/ast/typedesc-utils.js +157 -0
- package/dist/lang/ast/types/expr-result.d.ts +2 -1
- package/dist/lang/ast/types/expr-value.d.ts +11 -36
- package/dist/lang/ast/types/expr-value.js +27 -13
- package/dist/lang/ast/types/expression-def.d.ts +3 -2
- package/dist/lang/ast/types/expression-def.js +84 -60
- package/dist/lang/ast/types/global-name-space.js +2 -2
- package/dist/lang/ast/types/granular-result.d.ts +2 -2
- package/dist/lang/ast/types/granular-result.js +1 -1
- package/dist/lang/ast/types/space-field.js +2 -13
- package/dist/lang/ast/types/space-param.d.ts +3 -1
- package/dist/lang/ast/types/space-param.js +36 -4
- package/dist/lang/ast/types/time-result.d.ts +3 -4
- package/dist/lang/parse-log.d.ts +15 -15
- package/dist/lang/test/literals.spec.js +1 -1
- package/dist/lang/test/parse-expects.js +2 -2
- package/dist/model/malloy_types.d.ts +30 -32
- package/dist/model/malloy_types.js +25 -16
- package/package.json +1 -1
- package/dist/lang/ast/fragtype-utils.d.ts +0 -46
- package/dist/lang/ast/fragtype-utils.js +0 -115
|
@@ -21,11 +21,34 @@
|
|
|
21
21
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
24
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
48
|
exports.applyBinary = exports.getMorphicValue = exports.ExprDuration = exports.ExpressionDef = exports.ATNodeType = void 0;
|
|
26
49
|
const malloy_types_1 = require("../../../model/malloy_types");
|
|
50
|
+
const TDU = __importStar(require("../typedesc-utils"));
|
|
27
51
|
const ast_utils_1 = require("../ast-utils");
|
|
28
|
-
const fragtype_utils_1 = require("../fragtype-utils");
|
|
29
52
|
const expr_value_1 = require("./expr-value");
|
|
30
53
|
const time_utils_1 = require("../time-utils");
|
|
31
54
|
const granular_result_1 = require("./granular-result");
|
|
@@ -50,7 +73,7 @@ var ATNodeType;
|
|
|
50
73
|
class ExpressionDef extends malloy_element_1.MalloyElement {
|
|
51
74
|
constructor() {
|
|
52
75
|
super(...arguments);
|
|
53
|
-
this.legalChildTypes =
|
|
76
|
+
this.legalChildTypes = TDU.anyAtomicT;
|
|
54
77
|
}
|
|
55
78
|
granular() {
|
|
56
79
|
return false;
|
|
@@ -74,14 +97,14 @@ class ExpressionDef extends malloy_element_1.MalloyElement {
|
|
|
74
97
|
* @param eVal ...list of expressions that must match legalChildTypes
|
|
75
98
|
*/
|
|
76
99
|
typeCheck(eNode, eVal) {
|
|
77
|
-
if (eVal.
|
|
78
|
-
if (eVal.
|
|
100
|
+
if (eVal.type !== 'error' && !TDU.any(eVal, this.legalChildTypes)) {
|
|
101
|
+
if (eVal.type === 'sql native') {
|
|
79
102
|
eNode.logError('sql-native-not-allowed-in-expression', {
|
|
80
103
|
rawType: eVal.rawType,
|
|
81
104
|
});
|
|
82
105
|
}
|
|
83
106
|
else {
|
|
84
|
-
eNode.logError('expression-type-error', `'${this.elementType}' Can't use type ${
|
|
107
|
+
eNode.logError('expression-type-error', `'${this.elementType}' Can't use type ${TDU.inspect(eVal)}`);
|
|
85
108
|
}
|
|
86
109
|
return false;
|
|
87
110
|
}
|
|
@@ -126,15 +149,15 @@ class ExprDuration extends ExpressionDef {
|
|
|
126
149
|
this.n = n;
|
|
127
150
|
this.timeframe = timeframe;
|
|
128
151
|
this.elementType = 'duration';
|
|
129
|
-
this.legalChildTypes = [
|
|
152
|
+
this.legalChildTypes = [TDU.timestampT, TDU.dateT];
|
|
130
153
|
}
|
|
131
154
|
apply(fs, op, left) {
|
|
132
155
|
const lhs = left.getExpression(fs);
|
|
133
156
|
this.typeCheck(this, lhs);
|
|
134
|
-
if ((0, malloy_types_1.isTemporalField)(lhs.
|
|
157
|
+
if ((0, malloy_types_1.isTemporalField)(lhs.type) && (op === '+' || op === '-')) {
|
|
135
158
|
const num = this.n.getExpression(fs);
|
|
136
|
-
if (!
|
|
137
|
-
this.logError('invalid-duration-quantity', `Duration quantity needs number not '${num.
|
|
159
|
+
if (!TDU.typeEq(num, TDU.numberT)) {
|
|
160
|
+
this.logError('invalid-duration-quantity', `Duration quantity needs number not '${num.type}`);
|
|
138
161
|
return (0, ast_utils_1.errorFor)('illegal unit expression');
|
|
139
162
|
}
|
|
140
163
|
let resultGranularity;
|
|
@@ -144,12 +167,12 @@ class ExprDuration extends ExpressionDef {
|
|
|
144
167
|
if ((0, granular_result_1.isGranularResult)(lhs) && lhs.timeframe === this.timeframe) {
|
|
145
168
|
resultGranularity = lhs.timeframe;
|
|
146
169
|
}
|
|
147
|
-
if (lhs.
|
|
170
|
+
if (lhs.type === 'date' && !(0, malloy_types_1.isDateUnit)(this.timeframe)) {
|
|
148
171
|
return this.loggedErrorExpr('invalid-timeframe-for-time-offset', `Cannot offset date by ${this.timeframe}`);
|
|
149
172
|
}
|
|
150
173
|
return (0, expr_value_1.computedTimeResult)({
|
|
151
|
-
dataType: lhs.
|
|
152
|
-
value: (0, time_utils_1.timeOffset)(lhs.
|
|
174
|
+
dataType: { type: lhs.type },
|
|
175
|
+
value: (0, time_utils_1.timeOffset)(lhs.type, lhs.value, op, num.value, this.timeframe),
|
|
153
176
|
timeframe: resultGranularity,
|
|
154
177
|
from: [lhs, num],
|
|
155
178
|
});
|
|
@@ -159,7 +182,7 @@ class ExprDuration extends ExpressionDef {
|
|
|
159
182
|
getExpression(fs) {
|
|
160
183
|
const num = this.n.getExpression(fs);
|
|
161
184
|
return (0, expr_value_1.computedErrorExprValue)({
|
|
162
|
-
dataType: 'duration',
|
|
185
|
+
dataType: { type: 'duration' },
|
|
163
186
|
error: 'Duration is not a value',
|
|
164
187
|
from: [num],
|
|
165
188
|
});
|
|
@@ -167,30 +190,31 @@ class ExprDuration extends ExpressionDef {
|
|
|
167
190
|
}
|
|
168
191
|
exports.ExprDuration = ExprDuration;
|
|
169
192
|
function willMorphTo(ev, t) {
|
|
170
|
-
if (ev.
|
|
193
|
+
if (ev.type === t) {
|
|
171
194
|
return ev.value;
|
|
172
195
|
}
|
|
173
196
|
return ev.morphic && ev.morphic[t];
|
|
174
197
|
}
|
|
175
198
|
function getMorphicValue(mv, mt) {
|
|
176
|
-
if (mv.
|
|
199
|
+
if (mv.type === mt) {
|
|
177
200
|
return mv;
|
|
178
201
|
}
|
|
179
202
|
if (mv.morphic && mv.morphic[mt]) {
|
|
180
203
|
return {
|
|
181
|
-
|
|
182
|
-
dataType: mt,
|
|
204
|
+
type: mt,
|
|
183
205
|
value: mv.morphic[mt],
|
|
206
|
+
expressionType: mv.expressionType,
|
|
207
|
+
evalSpace: mv.evalSpace,
|
|
184
208
|
};
|
|
185
209
|
}
|
|
186
210
|
}
|
|
187
211
|
exports.getMorphicValue = getMorphicValue;
|
|
188
212
|
function timeCompare(left, lhs, op, rhs) {
|
|
189
|
-
const leftIsTime = (0, malloy_types_1.isTemporalField)(lhs.
|
|
190
|
-
const rightIsTime = (0, malloy_types_1.isTemporalField)(rhs.
|
|
213
|
+
const leftIsTime = (0, malloy_types_1.isTemporalField)(lhs.type);
|
|
214
|
+
const rightIsTime = (0, malloy_types_1.isTemporalField)(rhs.type);
|
|
191
215
|
const node = (0, binary_operators_1.getExprNode)(op);
|
|
192
216
|
if (leftIsTime && rightIsTime) {
|
|
193
|
-
if (lhs.
|
|
217
|
+
if (lhs.type !== rhs.type) {
|
|
194
218
|
const lval = willMorphTo(lhs, 'timestamp');
|
|
195
219
|
const rval = willMorphTo(rhs, 'timestamp');
|
|
196
220
|
if (lval && rval) {
|
|
@@ -202,24 +226,24 @@ function timeCompare(left, lhs, op, rhs) {
|
|
|
202
226
|
}
|
|
203
227
|
}
|
|
204
228
|
if ((leftIsTime || rightIsTime) &&
|
|
205
|
-
lhs.
|
|
206
|
-
rhs.
|
|
207
|
-
left.logError('time-comparison-type-mismatch', `Cannot compare a ${lhs.
|
|
229
|
+
lhs.type !== 'null' &&
|
|
230
|
+
rhs.type !== 'null') {
|
|
231
|
+
left.logError('time-comparison-type-mismatch', `Cannot compare a ${lhs.type} to a ${rhs.type}`);
|
|
208
232
|
return { node: 'false' };
|
|
209
233
|
}
|
|
210
234
|
return undefined;
|
|
211
235
|
}
|
|
212
236
|
function regexEqual(left, right) {
|
|
213
|
-
if (left.
|
|
214
|
-
if (right.
|
|
237
|
+
if (left.type === 'string') {
|
|
238
|
+
if (right.type === 'regular expression') {
|
|
215
239
|
return {
|
|
216
240
|
node: 'regexpMatch',
|
|
217
241
|
kids: { expr: left.value, regex: right.value },
|
|
218
242
|
};
|
|
219
243
|
}
|
|
220
244
|
}
|
|
221
|
-
else if (right.
|
|
222
|
-
if (left.
|
|
245
|
+
else if (right.type === 'string') {
|
|
246
|
+
if (left.type === 'regular expression') {
|
|
223
247
|
return {
|
|
224
248
|
node: 'regexpMatch',
|
|
225
249
|
kids: { expr: right.value, regex: left.value },
|
|
@@ -231,11 +255,11 @@ function regexEqual(left, right) {
|
|
|
231
255
|
function nullCompare(left, op, right) {
|
|
232
256
|
const not = op === '!=' || op === '!~';
|
|
233
257
|
const nullCmp = not ? 'is-not-null' : 'is-null';
|
|
234
|
-
if (left.
|
|
235
|
-
if (left.
|
|
258
|
+
if (left.type === 'null' || right.type === 'null') {
|
|
259
|
+
if (left.type !== 'null') {
|
|
236
260
|
return { node: nullCmp, e: left.value };
|
|
237
261
|
}
|
|
238
|
-
if (right.
|
|
262
|
+
if (right.type !== 'null') {
|
|
239
263
|
return { node: nullCmp, e: right.value };
|
|
240
264
|
}
|
|
241
265
|
return { node: not ? 'false' : 'true' };
|
|
@@ -251,14 +275,14 @@ function equality(fs, left, op, right) {
|
|
|
251
275
|
if (err)
|
|
252
276
|
return err;
|
|
253
277
|
// Unsupported types can be compare with null
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
if (!(oneNull ||
|
|
278
|
+
const lhRaw = malloy_types_1.TD.isSQL(lhs) ? lhs.rawType || 'typeless-left' : undefined;
|
|
279
|
+
const rhRaw = malloy_types_1.TD.isSQL(rhs) ? rhs.rawType || 'typeless-right' : undefined;
|
|
280
|
+
if (lhRaw || rhRaw) {
|
|
281
|
+
const oneNull = lhs.type === 'null' || rhs.type === 'null';
|
|
282
|
+
if (!(oneNull || lhRaw === rhRaw)) {
|
|
259
283
|
const noGo = unsupportError(left, lhs, right, rhs);
|
|
260
284
|
if (noGo) {
|
|
261
|
-
return { ...noGo,
|
|
285
|
+
return { ...noGo, type: 'boolean' };
|
|
262
286
|
}
|
|
263
287
|
}
|
|
264
288
|
}
|
|
@@ -266,11 +290,11 @@ function equality(fs, left, op, right) {
|
|
|
266
290
|
node,
|
|
267
291
|
kids: { left: lhs.value, right: rhs.value },
|
|
268
292
|
};
|
|
269
|
-
if (lhs.
|
|
293
|
+
if (lhs.type !== 'error' && rhs.type !== 'error') {
|
|
270
294
|
switch (op) {
|
|
271
295
|
case '~':
|
|
272
296
|
case '!~': {
|
|
273
|
-
if (lhs.
|
|
297
|
+
if (lhs.type !== 'string' || rhs.type !== 'string') {
|
|
274
298
|
let regexCmp = regexEqual(lhs, rhs);
|
|
275
299
|
if (regexCmp) {
|
|
276
300
|
if (op[0] === '!') {
|
|
@@ -292,7 +316,7 @@ function equality(fs, left, op, right) {
|
|
|
292
316
|
}
|
|
293
317
|
}
|
|
294
318
|
return (0, expr_value_1.computedExprValue)({
|
|
295
|
-
dataType: 'boolean',
|
|
319
|
+
dataType: { type: 'boolean' },
|
|
296
320
|
value,
|
|
297
321
|
from: [lhs, rhs],
|
|
298
322
|
});
|
|
@@ -305,14 +329,14 @@ function compare(fs, left, op, right) {
|
|
|
305
329
|
return err;
|
|
306
330
|
const noCompare = unsupportError(left, lhs, right, rhs);
|
|
307
331
|
if (noCompare) {
|
|
308
|
-
return { ...noCompare,
|
|
332
|
+
return { ...noCompare, type: 'boolean' };
|
|
309
333
|
}
|
|
310
334
|
const value = timeCompare(left, lhs, op, rhs) || {
|
|
311
335
|
node: (0, binary_operators_1.getExprNode)(op),
|
|
312
336
|
kids: { left: lhs.value, right: rhs.value },
|
|
313
337
|
};
|
|
314
338
|
return (0, expr_value_1.computedExprValue)({
|
|
315
|
-
dataType: 'boolean',
|
|
339
|
+
dataType: { type: 'boolean' },
|
|
316
340
|
value,
|
|
317
341
|
from: [lhs, rhs],
|
|
318
342
|
});
|
|
@@ -326,15 +350,15 @@ function numeric(fs, left, op, right) {
|
|
|
326
350
|
const noGo = unsupportError(left, lhs, right, rhs);
|
|
327
351
|
if (noGo)
|
|
328
352
|
return noGo;
|
|
329
|
-
if (lhs.
|
|
330
|
-
left.logError('arithmetic-operation-type-mismatch', `The '${op}' operator requires a number, not a '${lhs.
|
|
353
|
+
if (lhs.type !== 'number') {
|
|
354
|
+
left.logError('arithmetic-operation-type-mismatch', `The '${op}' operator requires a number, not a '${lhs.type}'`);
|
|
331
355
|
}
|
|
332
|
-
else if (rhs.
|
|
333
|
-
right.logError('arithmetic-operation-type-mismatch', `The '${op}' operator requires a number, not a '${rhs.
|
|
356
|
+
else if (rhs.type !== 'number') {
|
|
357
|
+
right.logError('arithmetic-operation-type-mismatch', `The '${op}' operator requires a number, not a '${rhs.type}'`);
|
|
334
358
|
}
|
|
335
359
|
else {
|
|
336
360
|
return (0, expr_value_1.computedExprValue)({
|
|
337
|
-
dataType: 'number',
|
|
361
|
+
dataType: { type: 'number' },
|
|
338
362
|
value: { node: op, kids: { left: lhs.value, right: rhs.value } },
|
|
339
363
|
from: [lhs, rhs],
|
|
340
364
|
});
|
|
@@ -348,21 +372,21 @@ function delta(fs, left, op, right) {
|
|
|
348
372
|
if (noGo) {
|
|
349
373
|
return noGo;
|
|
350
374
|
}
|
|
351
|
-
const timeLHS = (0, malloy_types_1.isTemporalField)(lhs.
|
|
375
|
+
const timeLHS = (0, malloy_types_1.isTemporalField)(lhs.type);
|
|
352
376
|
const err = errorCascade(timeLHS ? 'error' : 'number', lhs, rhs);
|
|
353
377
|
if (err)
|
|
354
378
|
return err;
|
|
355
379
|
if (timeLHS) {
|
|
356
380
|
let duration = right;
|
|
357
|
-
if (rhs.
|
|
381
|
+
if (rhs.type !== 'duration') {
|
|
358
382
|
if ((0, granular_result_1.isGranularResult)(lhs)) {
|
|
359
383
|
duration = new ExprDuration(right, lhs.timeframe);
|
|
360
384
|
}
|
|
361
|
-
else if (lhs.
|
|
385
|
+
else if (lhs.type === 'date') {
|
|
362
386
|
duration = new ExprDuration(right, 'day');
|
|
363
387
|
}
|
|
364
388
|
else {
|
|
365
|
-
return left.loggedErrorExpr('time-offset-type-mismatch', `Can not offset time by '${rhs.
|
|
389
|
+
return left.loggedErrorExpr('time-offset-type-mismatch', `Can not offset time by '${rhs.type}'`);
|
|
366
390
|
}
|
|
367
391
|
}
|
|
368
392
|
return duration.apply(fs, op, left);
|
|
@@ -402,10 +426,10 @@ function applyBinary(fs, left, op, right) {
|
|
|
402
426
|
const err = errorCascade('number', num, denom);
|
|
403
427
|
if (err)
|
|
404
428
|
return err;
|
|
405
|
-
if (num.
|
|
429
|
+
if (num.type !== 'number') {
|
|
406
430
|
left.logError('arithmetic-operation-type-mismatch', 'Numerator must be a number');
|
|
407
431
|
}
|
|
408
|
-
else if (denom.
|
|
432
|
+
else if (denom.type !== 'number') {
|
|
409
433
|
right.logError('arithmetic-operation-type-mismatch', 'Denominator must be a number');
|
|
410
434
|
}
|
|
411
435
|
else {
|
|
@@ -414,7 +438,7 @@ function applyBinary(fs, left, op, right) {
|
|
|
414
438
|
kids: { left: num.value, right: denom.value },
|
|
415
439
|
};
|
|
416
440
|
return (0, expr_value_1.computedExprValue)({
|
|
417
|
-
dataType: 'number',
|
|
441
|
+
dataType: { type: 'number' },
|
|
418
442
|
value: divmod,
|
|
419
443
|
from: [num, denom],
|
|
420
444
|
});
|
|
@@ -424,10 +448,10 @@ function applyBinary(fs, left, op, right) {
|
|
|
424
448
|
return left.loggedErrorExpr('unexpected-binary-operator', `Cannot use ${op} operator here`);
|
|
425
449
|
}
|
|
426
450
|
exports.applyBinary = applyBinary;
|
|
427
|
-
function errorCascade(
|
|
428
|
-
if (es.some(e => e.
|
|
451
|
+
function errorCascade(type, ...es) {
|
|
452
|
+
if (es.some(e => e.type === 'error')) {
|
|
429
453
|
return (0, expr_value_1.computedExprValue)({
|
|
430
|
-
dataType,
|
|
454
|
+
dataType: { type },
|
|
431
455
|
value: { node: 'error', message: 'cascading error' },
|
|
432
456
|
from: es,
|
|
433
457
|
});
|
|
@@ -438,16 +462,16 @@ function errorCascade(dataType, ...es) {
|
|
|
438
462
|
*/
|
|
439
463
|
function unsupportError(l, lhs, r, rhs) {
|
|
440
464
|
const ret = (0, expr_value_1.computedExprValue)({
|
|
441
|
-
dataType: lhs
|
|
465
|
+
dataType: lhs,
|
|
442
466
|
value: { node: 'error', message: 'sql-native unsupported' },
|
|
443
467
|
from: [lhs, rhs],
|
|
444
468
|
});
|
|
445
|
-
if (lhs.
|
|
469
|
+
if (lhs.type === 'sql native') {
|
|
446
470
|
l.logError('sql-native-not-allowed-in-expression', { rawType: lhs.rawType });
|
|
447
|
-
ret.
|
|
471
|
+
ret.type = rhs.type;
|
|
448
472
|
return ret;
|
|
449
473
|
}
|
|
450
|
-
if (rhs.
|
|
474
|
+
if (rhs.type === 'sql native') {
|
|
451
475
|
r.logError('sql-native-not-allowed-in-expression', { rawType: rhs.rawType });
|
|
452
476
|
return ret;
|
|
453
477
|
}
|
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.getDialectFunctions = exports.GlobalNameSpace = void 0;
|
|
26
26
|
const dialect_1 = require("../../../dialect");
|
|
27
27
|
const dialect_map_1 = require("../../../dialect/dialect_map");
|
|
28
|
+
const model_1 = require("../../../model");
|
|
28
29
|
/**
|
|
29
30
|
* This is a global namespace which exists in the root of all Documents
|
|
30
31
|
* and includes SQL function definitions.
|
|
@@ -55,8 +56,7 @@ function paramsEqual(a, b) {
|
|
|
55
56
|
return (param.isVariadic === otherParam.isVariadic &&
|
|
56
57
|
param.name === otherParam.name &&
|
|
57
58
|
param.allowedTypes.length === otherParam.allowedTypes.length &&
|
|
58
|
-
param.allowedTypes.every(t => otherParam.allowedTypes.some(ot => t.
|
|
59
|
-
t.expressionType === ot.expressionType)));
|
|
59
|
+
param.allowedTypes.every(t => otherParam.allowedTypes.some(ot => model_1.TD.eq(t, ot) && t.expressionType === ot.expressionType)));
|
|
60
60
|
}));
|
|
61
61
|
}
|
|
62
62
|
function getDialectFunctions() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TimestampUnit } from '../../../model/malloy_types';
|
|
2
2
|
import { ExprValue } from './expr-value';
|
|
3
3
|
import { TimeResult } from './time-result';
|
|
4
|
-
export
|
|
4
|
+
export type GranularResult = TimeResult & {
|
|
5
5
|
timeframe: TimestampUnit;
|
|
6
|
-
}
|
|
6
|
+
};
|
|
7
7
|
export declare function isGranularResult(v: ExprValue): v is GranularResult;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.isGranularResult = void 0;
|
|
26
26
|
function isGranularResult(v) {
|
|
27
|
-
if (v.
|
|
27
|
+
if (v.type === 'date' || v.type === 'timestamp') {
|
|
28
28
|
return v.timeframe !== undefined;
|
|
29
29
|
}
|
|
30
30
|
return false;
|
|
@@ -30,19 +30,8 @@ class SpaceField extends space_entry_1.SpaceEntry {
|
|
|
30
30
|
this.refType = 'field';
|
|
31
31
|
}
|
|
32
32
|
fieldTypeFromFieldDef(def) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
expressionType: 'scalar',
|
|
36
|
-
evalSpace: 'input',
|
|
37
|
-
};
|
|
38
|
-
if (def.expressionType) {
|
|
39
|
-
ref.expressionType = def.expressionType;
|
|
40
|
-
}
|
|
41
|
-
if (ref.dataType === 'sql native' &&
|
|
42
|
-
def.type === 'sql native' &&
|
|
43
|
-
def.rawType) {
|
|
44
|
-
ref.rawType = def.rawType;
|
|
45
|
-
}
|
|
33
|
+
const expressionType = def.expressionType || 'scalar';
|
|
34
|
+
const ref = { ...def, expressionType, evalSpace: 'input' };
|
|
46
35
|
return ref;
|
|
47
36
|
}
|
|
48
37
|
getQueryFieldDef(_fs) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Parameter, TypeDesc } from '../../../model/malloy_types';
|
|
1
|
+
import { FieldDefType, Parameter, TypeDesc } from '../../../model/malloy_types';
|
|
2
2
|
import { SpaceEntry } from './space-entry';
|
|
3
3
|
import { HasParameter } from '../parameters/has-parameter';
|
|
4
4
|
export declare abstract class SpaceParam extends SpaceEntry {
|
|
@@ -11,10 +11,12 @@ export declare class AbstractParameter extends SpaceParam {
|
|
|
11
11
|
_parameter: Parameter | undefined;
|
|
12
12
|
parameter(): Parameter;
|
|
13
13
|
typeDesc(): TypeDesc;
|
|
14
|
+
entryType(): FieldDefType;
|
|
14
15
|
}
|
|
15
16
|
export declare class DefinedParameter extends SpaceParam {
|
|
16
17
|
readonly paramDef: Parameter;
|
|
17
18
|
constructor(paramDef: Parameter);
|
|
18
19
|
parameter(): Parameter;
|
|
19
20
|
typeDesc(): TypeDesc;
|
|
21
|
+
entryType(): FieldDefType;
|
|
20
22
|
}
|
|
@@ -21,9 +21,33 @@
|
|
|
21
21
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
24
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
48
|
exports.DefinedParameter = exports.AbstractParameter = exports.SpaceParam = void 0;
|
|
26
49
|
const space_entry_1 = require("./space-entry");
|
|
50
|
+
const TDU = __importStar(require("../typedesc-utils"));
|
|
27
51
|
class SpaceParam extends space_entry_1.SpaceEntry {
|
|
28
52
|
constructor() {
|
|
29
53
|
super(...arguments);
|
|
@@ -44,9 +68,14 @@ class AbstractParameter extends SpaceParam {
|
|
|
44
68
|
return this._parameter;
|
|
45
69
|
}
|
|
46
70
|
typeDesc() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
return {
|
|
72
|
+
...TDU.atomicDef(this.parameter()),
|
|
73
|
+
expressionType: 'scalar',
|
|
74
|
+
evalSpace: 'constant',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
entryType() {
|
|
78
|
+
return this.parameter().type;
|
|
50
79
|
}
|
|
51
80
|
}
|
|
52
81
|
exports.AbstractParameter = AbstractParameter;
|
|
@@ -60,13 +89,16 @@ class DefinedParameter extends SpaceParam {
|
|
|
60
89
|
}
|
|
61
90
|
typeDesc() {
|
|
62
91
|
return {
|
|
63
|
-
|
|
92
|
+
...TDU.atomicDef(this.paramDef),
|
|
64
93
|
expressionType: 'scalar',
|
|
65
94
|
// TODO Not sure whether params are considered "input space". It seems like they
|
|
66
95
|
// could be input or constant, depending on usage (same as above).
|
|
67
96
|
evalSpace: 'input',
|
|
68
97
|
};
|
|
69
98
|
}
|
|
99
|
+
entryType() {
|
|
100
|
+
return this.paramDef.type;
|
|
101
|
+
}
|
|
70
102
|
}
|
|
71
103
|
exports.DefinedParameter = DefinedParameter;
|
|
72
104
|
//# sourceMappingURL=space-param.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TemporalTypeDef, TimestampUnit } from '../../../model/malloy_types';
|
|
2
2
|
import { ExprResult } from './expr-result';
|
|
3
|
-
export
|
|
4
|
-
dataType: TemporalFieldType;
|
|
3
|
+
export type TimeResult = TemporalTypeDef & ExprResult & {
|
|
5
4
|
timeframe?: TimestampUnit;
|
|
6
|
-
}
|
|
5
|
+
};
|
package/dist/lang/parse-log.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentLocation,
|
|
1
|
+
import { DocumentLocation, ExpressionValueType } from '../model/malloy_types';
|
|
2
2
|
import { EventStream } from '../runtime_types';
|
|
3
3
|
export type LogSeverity = 'error' | 'warn' | 'debug';
|
|
4
4
|
/**
|
|
@@ -37,22 +37,22 @@ export declare class BaseMessageLogger implements MessageLogger {
|
|
|
37
37
|
}
|
|
38
38
|
type MessageParameterTypes = {
|
|
39
39
|
'pick-type-does-not-match': {
|
|
40
|
-
pickType:
|
|
41
|
-
returnType:
|
|
40
|
+
pickType: ExpressionValueType;
|
|
41
|
+
returnType: ExpressionValueType;
|
|
42
42
|
};
|
|
43
43
|
'pick-else-type-does-not-match': {
|
|
44
|
-
elseType:
|
|
45
|
-
returnType:
|
|
44
|
+
elseType: ExpressionValueType;
|
|
45
|
+
returnType: ExpressionValueType;
|
|
46
46
|
};
|
|
47
47
|
'pick-default-type-does-not-match': {
|
|
48
|
-
defaultType:
|
|
49
|
-
returnType:
|
|
48
|
+
defaultType: ExpressionValueType;
|
|
49
|
+
returnType: ExpressionValueType;
|
|
50
50
|
};
|
|
51
51
|
'pick-missing-else': {};
|
|
52
52
|
'pick-missing-value': {};
|
|
53
53
|
'pick-illegal-partial': {};
|
|
54
54
|
'pick-when-must-be-boolean': {
|
|
55
|
-
whenType:
|
|
55
|
+
whenType: ExpressionValueType;
|
|
56
56
|
};
|
|
57
57
|
'experiment-not-enabled': {
|
|
58
58
|
experimentId: string;
|
|
@@ -318,19 +318,19 @@ type MessageParameterTypes = {
|
|
|
318
318
|
'not-yet-implemented': string;
|
|
319
319
|
'sql-case': string;
|
|
320
320
|
'case-then-type-does-not-match': {
|
|
321
|
-
thenType:
|
|
322
|
-
returnType:
|
|
321
|
+
thenType: ExpressionValueType;
|
|
322
|
+
returnType: ExpressionValueType;
|
|
323
323
|
};
|
|
324
324
|
'case-else-type-does-not-match': {
|
|
325
|
-
elseType:
|
|
326
|
-
returnType:
|
|
325
|
+
elseType: ExpressionValueType;
|
|
326
|
+
returnType: ExpressionValueType;
|
|
327
327
|
};
|
|
328
328
|
'case-when-must-be-boolean': {
|
|
329
|
-
whenType:
|
|
329
|
+
whenType: ExpressionValueType;
|
|
330
330
|
};
|
|
331
331
|
'case-when-type-does-not-match': {
|
|
332
|
-
whenType:
|
|
333
|
-
valueType:
|
|
332
|
+
whenType: ExpressionValueType;
|
|
333
|
+
valueType: ExpressionValueType;
|
|
334
334
|
};
|
|
335
335
|
'or-choices-only': string;
|
|
336
336
|
'sql-in': string;
|
|
@@ -89,7 +89,7 @@ describe('literals', () => {
|
|
|
89
89
|
const exprModel = new test_translator_1.BetaExpression(expr);
|
|
90
90
|
expect(exprModel).toTranslate();
|
|
91
91
|
const ir = exprModel.generated();
|
|
92
|
-
expect(ir.
|
|
92
|
+
expect(ir.type).toEqual(timeType);
|
|
93
93
|
if (timeframe) {
|
|
94
94
|
expect((0, granular_result_1.isGranularResult)(ir)).toBeTruthy();
|
|
95
95
|
if ((0, granular_result_1.isGranularResult)(ir)) {
|
|
@@ -208,8 +208,8 @@ expect.extend({
|
|
|
208
208
|
return ok;
|
|
209
209
|
}
|
|
210
210
|
const d = exprModel.generated();
|
|
211
|
-
const pass = d.
|
|
212
|
-
const msg = `Expression type ${d.
|
|
211
|
+
const pass = d.type === returnType;
|
|
212
|
+
const msg = `Expression type ${d.type} ${pass ? '=' : '!='} ${returnType}`;
|
|
213
213
|
return { pass, message: () => msg };
|
|
214
214
|
},
|
|
215
215
|
toLog: function (s, ...msgs) {
|