Skip to content

Commit e5e8c60

Browse files
committed
fix/implement pre-agg matching
1 parent 1d5e4f9 commit e5e8c60

File tree

2 files changed

+37
-48
lines changed

2 files changed

+37
-48
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseTimeDimension.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,14 @@ export class BaseTimeDimension extends BaseFilter {
241241
return this.dateRangeGranularity();
242242
}
243243

244-
return this.query.minGranularity(this.granularityObj.minGranularity(), this.dateRangeGranularity());
244+
// If we have granularity and date range, we need to check
245+
// that the interval and the granularity offset are stacked/fits with date range
246+
if (this.granularityObj.isPredefined() ||
247+
!this.granularityObj.isAlignedWithDateRange([this.dateFromFormatted(), this.dateToFormatted()])) {
248+
return this.query.minGranularity(this.granularityObj.minGranularity(), this.dateRangeGranularity());
249+
}
250+
251+
return this.granularityObj.granularity;
245252
}
246253
);
247254
}
@@ -262,11 +269,7 @@ export class BaseTimeDimension extends BaseFilter {
262269
}
263270

264271
public resolvedGranularity() {
265-
return this.granularityObj ? this.granularityObj.resolvedGranularity() : this.dateRangeGranularity();
266-
}
267-
268-
public isPredefinedGranularity(): boolean {
269-
return this.granularityObj?.isPredefined() || false;
272+
return this.granularityObj ? this.granularityObj.minGranularity() : this.dateRangeGranularity();
270273
}
271274

272275
public wildcardRange() {

packages/cubejs-schema-compiler/src/adapter/PreAggregations.js

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -439,34 +439,14 @@ export class PreAggregations {
439439
static sortTimeDimensionsWithRollupGranularity(timeDimensions) {
440440
return timeDimensions && R.sortBy(
441441
R.prop(0),
442-
timeDimensions.map(d => {
443-
const res = [d.expressionPath(), d.rollupGranularity()];
444-
if (d.isPredefinedGranularity()) {
445-
res.push(null);
446-
} else if (d.granularity && d.granularity !== res[1]) {
447-
// For custom granularities we need to add its name to the list (for exact matches)
448-
res.push(d.granularity);
449-
}
450-
return res;
451-
})
442+
timeDimensions.map(d => [d.expressionPath(), d.rollupGranularity(), d.granularityObj?.minGranularity()])
452443
) || [];
453444
}
454445

455446
static timeDimensionsAsIs(timeDimensions) {
456447
return timeDimensions && R.sortBy(
457448
R.prop(0),
458-
timeDimensions.map(d => {
459-
const res = [d.expressionPath()];
460-
const resolvedGranularity = d.resolvedGranularity();
461-
if (d.granularity && d.granularity !== resolvedGranularity) {
462-
// For custom granularities we need to add its name to the list (for exact matches)
463-
res.push(...[resolvedGranularity, d.granularity]);
464-
} else {
465-
// For query timeDimension without granularity we pass the resolved from dataRange as fallback
466-
res.push(resolvedGranularity);
467-
}
468-
return res;
469-
}),
449+
timeDimensions.map(d => [d.expressionPath(), d.resolvedGranularity(), d.granularityObj?.minGranularity()]),
470450
) || [];
471451
}
472452

@@ -557,8 +537,8 @@ export class PreAggregations {
557537
const qryTimeDimensions = references.allowNonStrictDateRangeMatch
558538
? transformedQuery.timeDimensions
559539
: transformedQuery.sortedTimeDimensions.map(t => t.slice(0, 2));
560-
// slice above is used to exclude possible custom granularity returned from sortTimeDimensionsWithRollupGranularity()
561-
540+
// slices above/below are used to exclude granularity on 3rd position returned from sortTimeDimensionsWithRollupGranularity()
541+
const qryDimensions = transformedQuery.timeDimensions.map(t => t.slice(0, 2));
562542
const backAliasMeasures = backAlias(references.measures);
563543
const backAliasSortedDimensions = backAlias(references.sortedDimensions || references.dimensions);
564544
const backAliasDimensions = backAlias(references.dimensions);
@@ -570,7 +550,7 @@ export class PreAggregations {
570550
R.equals(qryTimeDimensions, refTimeDimensions)
571551
) && (
572552
transformedQuery.isAdditive ||
573-
R.equals(transformedQuery.timeDimensions, refTimeDimensions)
553+
R.equals(qryDimensions, refTimeDimensions)
574554
) && (
575555
filterDimensionsSingleValueEqual &&
576556
references.dimensions.length === filterDimensionsSingleValueEqual.size &&
@@ -585,14 +565,29 @@ export class PreAggregations {
585565
};
586566

587567
/**
588-
* Wrap granularity string into an array.
589-
* @param {string} granularity
568+
* Expand granularity into array of granularity hierarchy.
569+
* resolvedGranularity might be a custom granularity name, in this case
570+
* we insert it into all expanded hierarchies using its minimal granularity passed
571+
* as minGranularity param
572+
* @param {string} resolvedGranularity
573+
* @param {string} minGranularity
590574
* @returns {Array<string>}
591575
*/
592-
const expandGranularity = (granularity) => (
593-
transformedQuery.granularityHierarchies[granularity] ||
594-
[granularity]
595-
);
576+
const expandGranularity = (resolvedGranularity, minGranularity) => {
577+
if (!resolvedGranularity) {
578+
return [];
579+
}
580+
581+
let predefinedHierarchy = transformedQuery.granularityHierarchies[resolvedGranularity];
582+
583+
if (predefinedHierarchy) {
584+
return predefinedHierarchy;
585+
}
586+
587+
predefinedHierarchy = transformedQuery.granularityHierarchies[minGranularity];
588+
// Custom granularity should be the first in list for exact match hit
589+
return [resolvedGranularity, ...predefinedHierarchy];
590+
};
596591

597592
/**
598593
* Determine whether time dimensions match to the window granularity or not.
@@ -624,18 +619,9 @@ export class PreAggregations {
624619
* @returns {Array<Array<string>>}
625620
*/
626621
const expandTimeDimension = (timeDimension) => {
627-
const [dimension, granularity, customOrResolvedGranularity] = timeDimension;
628-
const res = expandGranularity(granularity)
622+
const [dimension, resolvedGranularity, minGranularity] = timeDimension;
623+
return expandGranularity(resolvedGranularity, minGranularity)
629624
.map((newGranularity) => [dimension, newGranularity]);
630-
631-
if (customOrResolvedGranularity) {
632-
// For custom granularities we add it upfront to the list (for exact matches)
633-
// For queries with timeDimension but without granularity specified we use resolved
634-
// granularity from date range
635-
res.unshift([dimension, customOrResolvedGranularity]);
636-
}
637-
638-
return res;
639625
};
640626

641627
/**

0 commit comments

Comments
 (0)