@malloydata/malloy 0.0.80 → 0.0.81-dev230910191735
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.
|
@@ -124,7 +124,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
|
|
|
124
124
|
const noJoinField = !this.source && joinUsage.every(usage => usage.length === 0);
|
|
125
125
|
if (!noJoinField && !this.isSymmetricFunction()) {
|
|
126
126
|
const usagePaths = getJoinUsagePaths(sourceRelationship, joinUsage);
|
|
127
|
-
const joinError = validateUsagePaths(usagePaths);
|
|
127
|
+
const joinError = validateUsagePaths(this.elementType, usagePaths);
|
|
128
128
|
const message = sourceSpecified
|
|
129
129
|
? joinError
|
|
130
130
|
: 'Join path is required for this calculation';
|
|
@@ -254,14 +254,19 @@ function getJoinUsagePaths(sourceRelationship, joinUsage) {
|
|
|
254
254
|
}
|
|
255
255
|
return sourceToUsagePaths;
|
|
256
256
|
}
|
|
257
|
-
function validateUsagePaths(usagePaths) {
|
|
257
|
+
function validateUsagePaths(functionName, usagePaths) {
|
|
258
258
|
for (const path of usagePaths) {
|
|
259
259
|
for (const step of path) {
|
|
260
260
|
if (step.structRelationship.type === 'cross') {
|
|
261
|
-
return `Cannot compute
|
|
261
|
+
return `Cannot compute \`${functionName}\` across \`join_cross\` relationship \`${step.name}\``;
|
|
262
262
|
}
|
|
263
263
|
else if (step.structRelationship.type === 'many' && !step.reverse) {
|
|
264
|
-
return `Cannot compute
|
|
264
|
+
return `Cannot compute \`${functionName}\` across \`join_many\` relationship \`${step.name}\``;
|
|
265
|
+
}
|
|
266
|
+
else if (step.structRelationship.type === 'nested' &&
|
|
267
|
+
step.structRelationship.isArray &&
|
|
268
|
+
!step.reverse) {
|
|
269
|
+
return `Cannot compute \`${functionName}\` across repeated relationship \`${step.name}\``;
|
|
265
270
|
}
|
|
266
271
|
}
|
|
267
272
|
}
|
|
@@ -283,7 +288,7 @@ function suggestNewVersion(joinError, joinUsage, expr, func) {
|
|
|
283
288
|
}
|
|
284
289
|
}
|
|
285
290
|
const usagePaths = getJoinUsagePaths(longestOverlap, joinUsage);
|
|
286
|
-
const usageError = validateUsagePaths(usagePaths);
|
|
291
|
+
const usageError = validateUsagePaths(func, usagePaths);
|
|
287
292
|
// get rid of everything after the last many/cross
|
|
288
293
|
const indexFromEndOfLastMany = longestOverlap
|
|
289
294
|
.slice()
|
|
@@ -295,7 +300,7 @@ function suggestNewVersion(joinError, joinUsage, expr, func) {
|
|
|
295
300
|
: longestOverlap.length - indexFromEndOfLastMany;
|
|
296
301
|
const shortestOverlapWithMany = longestOverlap.slice(0, numJoinsToLastMany);
|
|
297
302
|
const shortUsagePaths = getJoinUsagePaths(shortestOverlapWithMany, joinUsage);
|
|
298
|
-
const shortUsageError = validateUsagePaths(shortUsagePaths);
|
|
303
|
+
const shortUsageError = validateUsagePaths(func, shortUsagePaths);
|
|
299
304
|
const longLocality = longestOverlap.length > 0
|
|
300
305
|
? longestOverlap.map(r => r.name).join('.')
|
|
301
306
|
: 'source';
|
|
@@ -176,6 +176,8 @@ describe('expressions', () => {
|
|
|
176
176
|
source: root is a {
|
|
177
177
|
rename: column is ai
|
|
178
178
|
rename: nested is astruct
|
|
179
|
+
rename: inline is aninline
|
|
180
|
+
rename: inline2 is anonrepeatedstruct
|
|
179
181
|
dimension: field is column * 2
|
|
180
182
|
dimension: many_field is many.column * 2
|
|
181
183
|
dimension: many_one_field is many.column + one.column
|
|
@@ -277,7 +279,7 @@ describe('expressions', () => {
|
|
|
277
279
|
expect(modelX `sum(many.column)`).translationToFailWith('Join path is required for this calculation; use `many.column.sum()`');
|
|
278
280
|
});
|
|
279
281
|
test('source.sum(many.column)', () => {
|
|
280
|
-
expect(modelX `source.sum(many.column)`).translationToFailWith('Cannot compute
|
|
282
|
+
expect(modelX `source.sum(many.column)`).translationToFailWith('Cannot compute `sum` across `join_many` relationship `many`; use `many.column.sum()`');
|
|
281
283
|
});
|
|
282
284
|
test('many.column.sum()', () => {
|
|
283
285
|
expect(modelX `many.column.sum()`).toTranslate();
|
|
@@ -295,19 +297,37 @@ describe('expressions', () => {
|
|
|
295
297
|
expect(modelX `source.sum(many.constant)`).toTranslate();
|
|
296
298
|
});
|
|
297
299
|
test('sum(nested.column)', () => {
|
|
298
|
-
expect(modelX `sum(nested.column)`).
|
|
300
|
+
expect(modelX `sum(nested.column)`).translationToFailWith('Join path is required for this calculation; use `nested.column.sum()`');
|
|
299
301
|
});
|
|
300
302
|
test('nested.column.sum()', () => {
|
|
301
303
|
expect(modelX `nested.column.sum()`).toTranslate();
|
|
302
304
|
});
|
|
303
305
|
test('source.sum(nested.column)', () => {
|
|
304
|
-
expect(modelX `source.sum(nested.column)`).
|
|
306
|
+
expect(modelX `source.sum(nested.column)`).translationToFailWith('Cannot compute `sum` across repeated relationship `nested`; use `nested.column.sum()`');
|
|
307
|
+
});
|
|
308
|
+
test('sum(inline.column)', () => {
|
|
309
|
+
expect(modelX `sum(inline.column)`).toTranslateWithWarnings('Join path is required for this calculation; use `inline.column.sum()` or `source.sum(inline.column)` to get a result weighted with respect to `source`');
|
|
310
|
+
});
|
|
311
|
+
test('inline.column.sum()', () => {
|
|
312
|
+
expect(modelX `inline.column.sum()`).toTranslate();
|
|
313
|
+
});
|
|
314
|
+
test('source.sum(inline.column)', () => {
|
|
315
|
+
expect(modelX `source.sum(inline.column)`).toTranslate();
|
|
316
|
+
});
|
|
317
|
+
test('sum(inline2.column)', () => {
|
|
318
|
+
expect(modelX `sum(inline2.column)`).toTranslateWithWarnings('Join path is required for this calculation; use `inline2.column.sum()` or `source.sum(inline2.column)` to get a result weighted with respect to `source`');
|
|
319
|
+
});
|
|
320
|
+
test('inline2.column.sum()', () => {
|
|
321
|
+
expect(modelX `inline2.column.sum()`).toTranslate();
|
|
322
|
+
});
|
|
323
|
+
test('source.sum(inline2.column)', () => {
|
|
324
|
+
expect(modelX `source.sum(inline2.column)`).toTranslate();
|
|
305
325
|
});
|
|
306
326
|
test('sum(many.field)', () => {
|
|
307
327
|
expect(modelX `sum(many.field)`).translationToFailWith('Join path is required for this calculation; use `many.field.sum()`');
|
|
308
328
|
});
|
|
309
329
|
test('source.sum(many.field)', () => {
|
|
310
|
-
expect(modelX `source.sum(many.field)`).translationToFailWith('Cannot compute
|
|
330
|
+
expect(modelX `source.sum(many.field)`).translationToFailWith('Cannot compute `sum` across `join_many` relationship `many`; use `many.field.sum()`');
|
|
311
331
|
});
|
|
312
332
|
test('many.field.sum()', () => {
|
|
313
333
|
expect(modelX `many.field.sum()`).toTranslate();
|
|
@@ -319,7 +339,7 @@ describe('expressions', () => {
|
|
|
319
339
|
expect(modelX `sum(many.field + many.field)`).translationToFailWith('Join path is required for this calculation; use `many.sum(many.field + many.field)`');
|
|
320
340
|
});
|
|
321
341
|
test('source.sum(many.field + many.field)', () => {
|
|
322
|
-
expect(modelX `source.sum(many.field + many.field)`).translationToFailWith('Cannot compute
|
|
342
|
+
expect(modelX `source.sum(many.field + many.field)`).translationToFailWith('Cannot compute `sum` across `join_many` relationship `many`; use `many.sum(many.field + many.field)`');
|
|
323
343
|
});
|
|
324
344
|
test('many.field + many.field.sum()', () => {
|
|
325
345
|
expect(modelX `many.field + many.field.sum()`).toTranslate();
|
|
@@ -331,7 +351,7 @@ describe('expressions', () => {
|
|
|
331
351
|
expect(modelX `sum(many_field)`).translationToFailWith('Join path is required for this calculation; use `many_field.sum()`');
|
|
332
352
|
});
|
|
333
353
|
test('source.sum(many_field)', () => {
|
|
334
|
-
expect(modelX `source.sum(many_field)`).translationToFailWith('Cannot compute
|
|
354
|
+
expect(modelX `source.sum(many_field)`).translationToFailWith('Cannot compute `sum` across `join_many` relationship `many`; use `many_field.sum()`');
|
|
335
355
|
});
|
|
336
356
|
test('many_field.sum()', () => {
|
|
337
357
|
expect(modelX `many_field.sum()`).toTranslate();
|
|
@@ -343,7 +363,7 @@ describe('expressions', () => {
|
|
|
343
363
|
expect(modelX `sum(one.many_field)`).translationToFailWith('Join path is required for this calculation; use `one.many_field.sum()`');
|
|
344
364
|
});
|
|
345
365
|
test('source.sum(one.many_field)', () => {
|
|
346
|
-
expect(modelX `source.sum(one.many_field)`).translationToFailWith('Cannot compute
|
|
366
|
+
expect(modelX `source.sum(one.many_field)`).translationToFailWith('Cannot compute `sum` across `join_many` relationship `many`; use `one.many_field.sum()`');
|
|
347
367
|
});
|
|
348
368
|
test('one.many_field.sum()', () => {
|
|
349
369
|
expect(modelX `one.many_field.sum()`).toTranslate();
|
|
@@ -382,7 +402,7 @@ describe('expressions', () => {
|
|
|
382
402
|
expect(modelX `one.avg(field)`).toTranslate();
|
|
383
403
|
});
|
|
384
404
|
test('cross.avg(field)', () => {
|
|
385
|
-
expect(modelX `cross.avg(field)`).translationToFailWith('Cannot compute
|
|
405
|
+
expect(modelX `cross.avg(field)`).translationToFailWith('Cannot compute `avg` across `join_cross` relationship `cross`; use `field.avg()`');
|
|
386
406
|
});
|
|
387
407
|
test('cross.avg(cross.field)', () => {
|
|
388
408
|
expect(modelX `cross.avg(cross.field)`).toTranslate();
|
|
@@ -55,6 +55,22 @@ const mockSchema = {
|
|
|
55
55
|
type: 'struct',
|
|
56
56
|
name: 'astruct',
|
|
57
57
|
structSource: { type: 'nested' },
|
|
58
|
+
structRelationship: { type: 'nested', isArray: true, field: 'foo' },
|
|
59
|
+
fields: [{ type: 'number', name: 'column', numberType: 'integer' }],
|
|
60
|
+
dialect: 'standardsql',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'struct',
|
|
64
|
+
name: 'anonrepeatedstruct',
|
|
65
|
+
structSource: { type: 'nested' },
|
|
66
|
+
structRelationship: { type: 'nested', isArray: false, field: 'foo' },
|
|
67
|
+
fields: [{ type: 'number', name: 'column', numberType: 'integer' }],
|
|
68
|
+
dialect: 'standardsql',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'struct',
|
|
72
|
+
name: 'aninline',
|
|
73
|
+
structSource: { type: 'nested' },
|
|
58
74
|
structRelationship: { type: 'inline' },
|
|
59
75
|
fields: [{ type: 'number', name: 'column', numberType: 'integer' }],
|
|
60
76
|
dialect: 'standardsql',
|