@@ -49,6 +49,10 @@ export type PreAggregationForCube = {
4949 references : PreAggregationReferences ;
5050} ;
5151
52+ export type EvaluateReferencesContext = {
53+ inPreAggEvaluation ?: boolean ;
54+ } ;
55+
5256export type BaseMember = BaseDimension | BaseMeasure | BaseFilter | BaseGroupFilter | BaseSegment ;
5357
5458export type CanUsePreAggregationFn = ( references : PreAggregationReferences ) => boolean ;
@@ -582,12 +586,15 @@ export class PreAggregations {
582586 const dimensionsTrimmed = references
583587 . dimensions
584588 . map ( d => CubeSymbols . joinHintFromPath ( d ) . path ) ;
589+ const multipliedMeasuresTrimmed = references
590+ . multipliedMeasures ?. map ( m => CubeSymbols . joinHintFromPath ( m ) . path ) ;
585591
586592 return {
587593 ...references ,
588594 dimensions : dimensionsTrimmed ,
589595 measures : measuresTrimmed ,
590596 timeDimensions : timeDimensionsTrimmed ,
597+ multipliedMeasures : multipliedMeasuresTrimmed ,
591598 } ;
592599 }
593600
@@ -722,6 +729,19 @@ export class PreAggregations {
722729 // TODO remove this in favor of matching with join path
723730 const referencesTrimmed = trimmedReferences ( references ) ;
724731
732+ // Even if there are no multiplied measures in the query (because no multiplier dimensions are requested)
733+ // but the same measures are multiplied in the pre-aggregation, we can't use pre-aggregation
734+ // for such queries.
735+ if ( referencesTrimmed . multipliedMeasures ) {
736+ const backAliasMultipliedMeasures = backAlias ( referencesTrimmed . multipliedMeasures ) ;
737+
738+ if ( transformedQuery . leafMeasures . some ( m => referencesTrimmed . multipliedMeasures . includes ( m ) ) ||
739+ transformedQuery . measures . some ( m => backAliasMultipliedMeasures . includes ( m ) )
740+ ) {
741+ return false ;
742+ }
743+ }
744+
725745 const dimensionsMatch = ( dimensions , doBackAlias ) => R . all (
726746 d => (
727747 doBackAlias ?
@@ -1193,11 +1213,11 @@ export class PreAggregations {
11931213 ) ;
11941214 }
11951215
1196- public rollupPreAggregationQuery ( cube : string , aggregation ) : BaseQuery {
1216+ public rollupPreAggregationQuery ( cube : string , aggregation : PreAggregationDefinition , context : EvaluateReferencesContext = { } ) : BaseQuery {
11971217 // `this.evaluateAllReferences` will retain not only members, but their join path as well, and pass join hints
11981218 // to subquery. Otherwise, members in subquery would regenerate new join tree from clean state,
11991219 // and it can be different from expected by join path in pre-aggregation declaration
1200- const references = this . evaluateAllReferences ( cube , aggregation ) ;
1220+ const references = this . evaluateAllReferences ( cube , aggregation , null , context ) ;
12011221 const cubeQuery = this . query . newSubQueryForCube ( cube , { } ) ;
12021222 return this . query . newSubQueryForCube ( cube , {
12031223 rowLimit : null ,
@@ -1225,7 +1245,7 @@ export class PreAggregations {
12251245 } ) ;
12261246 }
12271247
1228- public autoRollupPreAggregationQuery ( cube : string , aggregation ) : BaseQuery {
1248+ public autoRollupPreAggregationQuery ( cube : string , aggregation : PreAggregationDefinition ) : BaseQuery {
12291249 return this . query . newSubQueryForCube (
12301250 cube ,
12311251 {
@@ -1266,13 +1286,18 @@ export class PreAggregations {
12661286 . toLowerCase ( ) ;
12671287 }
12681288
1269- private evaluateAllReferences ( cube : string , aggregation : PreAggregationDefinition , preAggregationName : string | null = null ) : PreAggregationReferences {
1289+ private evaluateAllReferences ( cube : string , aggregation : PreAggregationDefinition , preAggregationName : string | null = null , context : EvaluateReferencesOptions = { } ) : PreAggregationReferences {
12701290 // TODO build a join tree for all references, so they would always include full join path
12711291 // Even for preaggregation references without join path
12721292 // It is necessary to be able to match query and preaggregation based on full join tree
12731293
12741294 const evaluateReferences = ( ) => {
12751295 const references = this . query . cubeEvaluator . evaluatePreAggregationReferences ( cube , aggregation ) ;
1296+ if ( ! context . inPreAggEvaluation ) {
1297+ const preAggQuery = this . query . preAggregationQueryForSqlEvaluation ( cube , aggregation , { inPreAggEvaluation : true } ) ;
1298+ const aggregateMeasures = preAggQuery ?. fullKeyQueryAggregateMeasures ( { hasMultipliedForPreAggregation : true } ) ;
1299+ references . multipliedMeasures = aggregateMeasures ?. multipliedMeasures ?. map ( m => m . measure ) ;
1300+ }
12761301 if ( aggregation . type === 'rollupLambda' ) {
12771302 if ( references . rollups . length > 0 ) {
12781303 const [ firstLambdaCube ] = this . query . cubeEvaluator . parsePath ( 'preAggregations' , references . rollups [ 0 ] ) ;
0 commit comments