@@ -289,6 +289,11 @@ export class BaseQuery {
289289 } ) . filter ( R . identity ) . map ( this . newTimeDimension . bind ( this ) ) ;
290290 this . allFilters = this . timeDimensions . concat ( this . segments ) . concat ( this . filters ) ;
291291 this . useNativeSqlPlanner = this . options . useNativeSqlPlanner ?? getEnv ( 'nativeSqlPlanner' ) ;
292+ this . canUseNativeSqlPlannerPreAggregation = false ;
293+ if ( this . useNativeSqlPlanner ) {
294+ const hasMultiStageMeasures = this . fullKeyQueryAggregateMeasures ( { hasMultipliedForPreAggregation : true } ) . multiStageMembers . length > 0 ;
295+ this . canUseNativeSqlPlannerPreAggregation = hasMultiStageMeasures ;
296+ }
292297 this . prebuildJoin ( ) ;
293298
294299 this . cubeAliasPrefix = this . options . cubeAliasPrefix ;
@@ -471,6 +476,19 @@ export class BaseQuery {
471476 }
472477
473478 newDimension ( dimensionPath ) {
479+ if ( typeof dimensionPath === 'string' ) {
480+ const memberArr = dimensionPath . split ( '.' ) ;
481+ if ( memberArr . length > 3 &&
482+ memberArr [ memberArr . length - 2 ] === 'granularities' &&
483+ this . cubeEvaluator . isDimension ( memberArr . slice ( 0 , - 2 ) ) ) {
484+ return this . newTimeDimension (
485+ {
486+ dimension : this . cubeEvaluator . pathFromArray ( memberArr . slice ( 0 , - 2 ) ) ,
487+ granularity : memberArr [ memberArr . length - 1 ]
488+ }
489+ ) ;
490+ }
491+ }
474492 return new BaseDimension ( this , dimensionPath ) ;
475493 }
476494
@@ -636,38 +654,39 @@ export class BaseQuery {
636654 * @returns {[string, Array<unknown>] }
637655 */
638656 buildSqlAndParams ( exportAnnotatedSql ) {
639- if ( ! this . options . preAggregationQuery && ! this . options . disableExternalPreAggregations && this . externalQueryClass ) {
640- if ( this . externalPreAggregationQuery ( ) ) { // TODO performance
641- return this . externalQuery ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
642- }
643- }
644-
645657 if ( this . useNativeSqlPlanner ) {
646658 let isRelatedToPreAggregation = false ;
647- if ( this . options . preAggregationQuery ) {
648- isRelatedToPreAggregation = true ;
649- } else if ( ! this . options . disableExternalPreAggregations && this . externalQueryClass ) {
650- if ( this . externalPreAggregationQuery ( ) ) {
659+
660+ if ( ! this . canUseNativeSqlPlannerPreAggregation ) {
661+ if ( this . options . preAggregationQuery ) {
651662 isRelatedToPreAggregation = true ;
652- }
653- } else {
654- let preAggForQuery =
655- this . preAggregations . findPreAggregationForQuery ( ) ;
656- if ( this . options . disableExternalPreAggregations && preAggForQuery && preAggForQuery . preAggregation . external ) {
657- preAggForQuery = undefined ;
658- }
659- if ( preAggForQuery ) {
663+ } else if ( ! this . options . disableExternalPreAggregations && this . externalQueryClass && this . externalPreAggregationQuery ( ) ) {
660664 isRelatedToPreAggregation = true ;
665+ } else {
666+ let preAggForQuery =
667+ this . preAggregations . findPreAggregationForQuery ( ) ;
668+ if ( this . options . disableExternalPreAggregations && preAggForQuery && preAggForQuery . preAggregation . external ) {
669+ preAggForQuery = undefined ;
670+ }
671+ if ( preAggForQuery ) {
672+ isRelatedToPreAggregation = true ;
673+ }
661674 }
662- }
663675
664- if ( isRelatedToPreAggregation ) {
665- return this . newQueryWithoutNative ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
676+ if ( isRelatedToPreAggregation ) {
677+ return this . newQueryWithoutNative ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
678+ }
666679 }
667680
668681 return this . buildSqlAndParamsRust ( exportAnnotatedSql ) ;
669682 }
670683
684+ if ( ! this . options . preAggregationQuery && ! this . options . disableExternalPreAggregations && this . externalQueryClass ) {
685+ if ( this . externalPreAggregationQuery ( ) ) { // TODO performance
686+ return this . externalQuery ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
687+ }
688+ }
689+
671690 return this . compilers . compiler . withQuery (
672691 this ,
673692 ( ) => this . cacheValue (
@@ -703,8 +722,8 @@ export class BaseQuery {
703722 offset : this . options . offset ? this . options . offset . toString ( ) : null ,
704723 baseTools : this ,
705724 ungrouped : this . options . ungrouped ,
706- exportAnnotatedSql : exportAnnotatedSql === true
707-
725+ exportAnnotatedSql : exportAnnotatedSql === true ,
726+ preAggregationQuery : this . options . preAggregationQuery
708727 } ;
709728
710729 const buildResult = nativeBuildSqlAndParams ( queryParams ) ;
@@ -718,9 +737,57 @@ export class BaseQuery {
718737 }
719738
720739 const res = buildResult . result ;
740+ const [ query , params , preAggregation ] = res ;
721741 // FIXME
722- res [ 1 ] = [ ...res [ 1 ] ] ;
723- return res ;
742+ const paramsArray = [ ...params ] ;
743+ if ( preAggregation ) {
744+ this . preAggregations . preAggregationForQuery = preAggregation ;
745+ }
746+ return [ query , paramsArray ] ;
747+ }
748+
749+ // FIXME Temporary solution
750+ findPreAggregationForQueryRust ( ) {
751+ let optionsOrder = this . options . order ;
752+ if ( optionsOrder && ! Array . isArray ( optionsOrder ) ) {
753+ optionsOrder = [ optionsOrder ] ;
754+ }
755+ const order = optionsOrder ? R . pipe (
756+ R . map ( ( hash ) => ( ( ! hash || ! hash . id ) ? null : hash ) ) ,
757+ R . reject ( R . isNil ) ,
758+ ) ( optionsOrder ) : undefined ;
759+
760+ const queryParams = {
761+ measures : this . options . measures ,
762+ dimensions : this . options . dimensions ,
763+ segments : this . options . segments ,
764+ timeDimensions : this . options . timeDimensions ,
765+ timezone : this . options . timezone ,
766+ joinGraph : this . joinGraph ,
767+ cubeEvaluator : this . cubeEvaluator ,
768+ order,
769+ filters : this . options . filters ,
770+ limit : this . options . limit ? this . options . limit . toString ( ) : null ,
771+ rowLimit : this . options . rowLimit ? this . options . rowLimit . toString ( ) : null ,
772+ offset : this . options . offset ? this . options . offset . toString ( ) : null ,
773+ baseTools : this ,
774+ ungrouped : this . options . ungrouped ,
775+ exportAnnotatedSql : false ,
776+ preAggregationQuery : this . options . preAggregationQuery
777+ } ;
778+
779+ const buildResult = nativeBuildSqlAndParams ( queryParams ) ;
780+
781+ if ( buildResult . error ) {
782+ if ( buildResult . error . cause === 'User' ) {
783+ throw new UserError ( buildResult . error . message ) ;
784+ } else {
785+ throw new Error ( buildResult . error . message ) ;
786+ }
787+ }
788+
789+ const [ , , preAggregation ] = buildResult . result ;
790+ return preAggregation ;
724791 }
725792
726793 allCubeMembers ( path ) {
@@ -743,6 +810,10 @@ export class BaseQuery {
743810 return timeSeriesFromCustomInterval ( granularityInterval , dateRange , moment ( origin ) , { timestampPrecision : 3 } ) ;
744811 }
745812
813+ getPreAggregationByName ( cube , preAggregationName ) {
814+ return this . preAggregations . getRollupPreAggregationByName ( cube , preAggregationName ) ;
815+ }
816+
746817 get shouldReuseParams ( ) {
747818 return false ;
748819 }
@@ -922,7 +993,6 @@ export class BaseQuery {
922993 const renderedWithQueries = withQueries . map ( q => this . renderWithQuery ( q ) ) ;
923994
924995 let toJoin ;
925-
926996 if ( this . options . preAggregationQuery ) {
927997 const allRegular = regularMeasures . concat (
928998 cumulativeMeasures
@@ -1153,7 +1223,6 @@ export class BaseQuery {
11531223
11541224 const multipliedMeasures = measuresToRender ( true , false ) ( measureToHierarchy ) ;
11551225 const regularMeasures = measuresToRender ( false , false ) ( measureToHierarchy ) ;
1156-
11571226 const cumulativeMeasures =
11581227 R . pipe (
11591228 R . map ( multiplied => R . xprod ( [ multiplied ] , measuresToRender ( multiplied , true ) ( measureToHierarchy ) ) ) ,
@@ -3228,7 +3297,7 @@ export class BaseQuery {
32283297 }
32293298
32303299 newSubQueryForCube ( cube , options ) {
3231- options = { ...options , useNativeSqlPlanner : false } ; // We don't use tesseract for pre-aggregations generation yet
3300+ options = { ...options } ;
32323301 if ( this . options . queryFactory ) {
32333302 // When dealing with rollup joins, it's crucial to use the correct parameter allocator for the specific cube in use.
32343303 // By default, we'll use BaseQuery, but it's important to note that different databases (Oracle, PostgreSQL, MySQL, Druid, etc.)
0 commit comments