@@ -39,6 +39,7 @@ export type PreAggregationForQuery = {
3939 preAggregationName : string ;
4040 cube : string ;
4141 canUsePreAggregation : boolean ;
42+ leafMeasureMatch ?: boolean ;
4243 preAggregationId : string ;
4344 preAggregation : PreAggregationDefinitionExtended ;
4445 references : PreAggregationReferences ;
@@ -78,7 +79,8 @@ export type RollupJoinItem = JoinEdgeWithMembers & {
7879
7980export type RollupJoin = RollupJoinItem [ ] ;
8081
81- export type CanUsePreAggregationFn = ( references : PreAggregationReferences ) => boolean ;
82+ export type CanUsePreAggregationResult = { canUse : boolean ; leafMeasureMatch : boolean } ;
83+ export type CanUsePreAggregationFn = ( references : PreAggregationReferences ) => CanUsePreAggregationResult ;
8284
8385/**
8486 * TODO: Write a real type.
@@ -642,15 +644,15 @@ export class PreAggregations {
642644 /**
643645 * Determine whether pre-aggregation can be used or not.
644646 */
645- const canUsePreAggregationNotAdditive : CanUsePreAggregationFn = ( references : PreAggregationReferences ) : boolean => {
647+ const canUsePreAggregationNotAdditive : CanUsePreAggregationFn = ( references : PreAggregationReferences ) : CanUsePreAggregationResult => {
646648 const qryTimeDimensions = references . allowNonStrictDateRangeMatch
647649 ? transformedQuery . timeDimensions
648650 : transformedQuery . sortedTimeDimensions ;
649651
650652 const refTimeDimensions = backAlias ( sortTimeDimensions ( references . timeDimensions ) ) ;
651653 const backAliasMeasures = backAlias ( references . measures ) ;
652654 const backAliasDimensions = backAlias ( references . dimensions ) ;
653- return ( (
655+ const canUse = ( (
654656 transformedQuery . hasNoTimeDimensionsWithoutGranularity
655657 ) && (
656658 ! transformedQuery . hasCumulativeMeasures
@@ -670,6 +672,7 @@ export class PreAggregations {
670672 // TODO do we need backAlias here?
671673 R . all ( m => backAliasMeasures . includes ( m ) , transformedQuery . leafMeasures )
672674 ) ) ;
675+ return { canUse : ! ! canUse , leafMeasureMatch : false } ;
673676 } ;
674677
675678 /**
@@ -714,7 +717,7 @@ export class PreAggregations {
714717 . map ( ( newGranularity ) => [ dimension , newGranularity ] ) ;
715718 } ;
716719
717- const canUsePreAggregationLeafMeasureAdditive : CanUsePreAggregationFn = ( references ) : boolean => {
720+ const canUsePreAggregationLeafMeasureAdditive : CanUsePreAggregationFn = ( references ) : CanUsePreAggregationResult => {
718721 /**
719722 * Array of 2-element arrays with dimension and granularity.
720723 * @type {Array<Array<string>> }
@@ -736,7 +739,7 @@ export class PreAggregations {
736739 if ( transformedQuery . leafMeasures . some ( m => references . multipliedMeasures ?. includes ( m ) ) ||
737740 transformedQuery . measures . some ( m => backAliasMultipliedMeasures . includes ( m ) )
738741 ) {
739- return false ;
742+ return { canUse : false , leafMeasureMatch : true } ;
740743 }
741744 }
742745
@@ -773,32 +776,36 @@ export class PreAggregations {
773776 dimensionsMatch ( transformedQuery . sortedUsedCubePrimaryKeys , true ) || dimensionsMatch ( transformedQuery . sortedUsedCubePrimaryKeys , false )
774777 )
775778 ) {
776- return false ;
779+ return { canUse : false , leafMeasureMatch : true } ;
777780 }
778781 }
779782
780783 const backAliasMeasures = backAlias ( references . measures ) ;
781- return ( (
784+ const canUse = ( (
782785 windowGranularityMatches ( references )
783786 ) && (
784787 R . all (
785788 ( m : string ) => references . measures . indexOf ( m ) !== - 1 ,
786789 references . rollups . length > 0 ? transformedQuery . leafMeasures : transformedQuery . leafMeasuresFullPaths ,
787- ) || R . all (
790+ ) || ( transformedQuery . isAdditive && R . all (
788791 m => backAliasMeasures . indexOf ( m ) !== - 1 ,
789792 transformedQuery . measures ,
790- )
793+ ) )
791794 ) && (
792795 dimensionsMatch ( transformedQuery . sortedDimensions , true ) && timeDimensionsMatch ( queryTimeDimensionsList , true ) ||
793796 dimensionsMatch ( transformedQuery . ownedDimensions , false ) && timeDimensionsMatch ( ownedQueryTimeDimensionsList , false )
794797 ) ) ;
798+ return { canUse : ! ! canUse , leafMeasureMatch : true } ;
795799 } ;
796800
797801 const canUseFn : CanUsePreAggregationFn =
798802 (
799803 transformedQuery . leafMeasureAdditive && ! transformedQuery . hasMultipliedMeasures && ! transformedQuery . hasMultiStage || transformedQuery . ungrouped
800- ) ? ( ( r : PreAggregationReferences ) : boolean => canUsePreAggregationLeafMeasureAdditive ( r ) ||
801- canUsePreAggregationNotAdditive ( r ) )
804+ ) ? ( ( r : PreAggregationReferences ) : CanUsePreAggregationResult => {
805+ const leaf = canUsePreAggregationLeafMeasureAdditive ( r ) ;
806+ if ( leaf . canUse ) return leaf ;
807+ return canUsePreAggregationNotAdditive ( r ) ;
808+ } )
802809 : canUsePreAggregationNotAdditive ;
803810
804811 if ( refs ) {
@@ -935,7 +942,7 @@ export class PreAggregations {
935942 }
936943
937944 public getRollupPreAggregationByName ( cube , preAggregationName ) : PreAggregationForQueryWithTableName | { } {
938- const canUsePreAggregation = ( ) => true ;
945+ const canUsePreAggregation : CanUsePreAggregationFn = ( ) => ( { canUse : true , leafMeasureMatch : false } ) ;
939946 const preAggregation = R . pipe (
940947 R . toPairs ,
941948 R . filter ( ( [ _ , a ] ) => a . type === 'rollup' || a . type === 'rollupJoin' || a . type === 'rollupLambda' ) ,
@@ -1079,13 +1086,17 @@ export class PreAggregations {
10791086 canUsePreAggregation : CanUsePreAggregationFn
10801087 ) : PreAggregationForQuery {
10811088 const references = this . evaluateAllReferences ( cube , preAggregation , preAggregationName ) ;
1089+ const rollupResult = preAggregation . type === 'rollup'
1090+ ? canUsePreAggregation ( references )
1091+ : { canUse : false , leafMeasureMatch : false } ;
10821092 const preAggObj : PreAggregationForQuery = {
10831093 preAggregationName,
10841094 preAggregation,
10851095 cube,
10861096 // For rollupJoin and rollupLambda we need to enrich references with data
10871097 // from the underlying rollups which are collected later;
1088- canUsePreAggregation : preAggregation . type === 'rollup' ? canUsePreAggregation ( references ) : false ,
1098+ canUsePreAggregation : rollupResult . canUse ,
1099+ leafMeasureMatch : rollupResult . leafMeasureMatch ,
10891100 references,
10901101 preAggregationId : `${ cube } .${ preAggregationName } `
10911102 } ;
@@ -1107,10 +1118,12 @@ export class PreAggregations {
11071118 references . rollupsReferences . push ( preAgg . references ) ;
11081119 } ) ;
11091120 const rollupJoin = this . buildRollupJoin ( preAggObj , preAggregationsToJoin ) ;
1121+ const joinResult = canUsePreAggregation ( references ) ;
11101122
11111123 return {
11121124 ...preAggObj ,
1113- canUsePreAggregation : canUsePreAggregation ( references ) ,
1125+ canUsePreAggregation : joinResult . canUse ,
1126+ leafMeasureMatch : joinResult . leafMeasureMatch ,
11141127 preAggregationsToJoin,
11151128 rollupJoin,
11161129 } ;
@@ -1160,9 +1173,11 @@ export class PreAggregations {
11601173 referencedPreAggregations . forEach ( preAgg => {
11611174 references . rollupsReferences . push ( preAgg . references ) ;
11621175 } ) ;
1176+ const lambdaResult = canUsePreAggregation ( references ) ;
11631177 return {
11641178 ...preAggObj ,
1165- canUsePreAggregation : canUsePreAggregation ( references ) ,
1179+ canUsePreAggregation : lambdaResult . canUse ,
1180+ leafMeasureMatch : lambdaResult . leafMeasureMatch ,
11661181 referencedPreAggregations,
11671182 } ;
11681183 } else {
@@ -1566,6 +1581,13 @@ export class PreAggregations {
15661581 return Object . fromEntries ( measures
15671582 . flatMap ( path => {
15681583 const measure = this . query . newMeasure ( path ) ;
1584+
1585+ // Skip non-additive measures in leaf-measure match mode —
1586+ // they will be recomputed from their leaf measures
1587+ if ( preAggregationForQuery . leafMeasureMatch && ! measure . isAdditive ( ) ) {
1588+ return [ ] ;
1589+ }
1590+
15691591 const measurePath = measure . path ( ) ;
15701592 const column = this . query . ungrouped ? measure . aliasName ( ) : ( this . query . aggregateOnGroupedColumn (
15711593 measure . measureDefinition ( ) ,
0 commit comments