@@ -289,6 +289,11 @@ export class BaseQuery {
289
289
} ) . filter ( R . identity ) . map ( this . newTimeDimension . bind ( this ) ) ;
290
290
this . allFilters = this . timeDimensions . concat ( this . segments ) . concat ( this . filters ) ;
291
291
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
+ }
292
297
this . prebuildJoin ( ) ;
293
298
294
299
this . cubeAliasPrefix = this . options . cubeAliasPrefix ;
@@ -471,6 +476,19 @@ export class BaseQuery {
471
476
}
472
477
473
478
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
+ }
474
492
return new BaseDimension ( this , dimensionPath ) ;
475
493
}
476
494
@@ -636,38 +654,39 @@ export class BaseQuery {
636
654
* @returns {[string, Array<unknown>] }
637
655
*/
638
656
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
-
645
657
if ( this . useNativeSqlPlanner ) {
646
658
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 ) {
651
662
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 ( ) ) {
660
664
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
+ }
661
674
}
662
- }
663
675
664
- if ( isRelatedToPreAggregation ) {
665
- return this . newQueryWithoutNative ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
676
+ if ( isRelatedToPreAggregation ) {
677
+ return this . newQueryWithoutNative ( ) . buildSqlAndParams ( exportAnnotatedSql ) ;
678
+ }
666
679
}
667
680
668
681
return this . buildSqlAndParamsRust ( exportAnnotatedSql ) ;
669
682
}
670
683
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
+
671
690
return this . compilers . compiler . withQuery (
672
691
this ,
673
692
( ) => this . cacheValue (
@@ -703,8 +722,8 @@ export class BaseQuery {
703
722
offset : this . options . offset ? this . options . offset . toString ( ) : null ,
704
723
baseTools : this ,
705
724
ungrouped : this . options . ungrouped ,
706
- exportAnnotatedSql : exportAnnotatedSql === true
707
-
725
+ exportAnnotatedSql : exportAnnotatedSql === true ,
726
+ preAggregationQuery : this . options . preAggregationQuery
708
727
} ;
709
728
710
729
const buildResult = nativeBuildSqlAndParams ( queryParams ) ;
@@ -718,9 +737,57 @@ export class BaseQuery {
718
737
}
719
738
720
739
const res = buildResult . result ;
740
+ const [ query , params , preAggregation ] = res ;
721
741
// 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 ;
724
791
}
725
792
726
793
allCubeMembers ( path ) {
@@ -743,6 +810,10 @@ export class BaseQuery {
743
810
return timeSeriesFromCustomInterval ( granularityInterval , dateRange , moment ( origin ) , { timestampPrecision : 3 } ) ;
744
811
}
745
812
813
+ getPreAggregationByName ( cube , preAggregationName ) {
814
+ return this . preAggregations . getRollupPreAggregationByName ( cube , preAggregationName ) ;
815
+ }
816
+
746
817
get shouldReuseParams ( ) {
747
818
return false ;
748
819
}
@@ -922,7 +993,6 @@ export class BaseQuery {
922
993
const renderedWithQueries = withQueries . map ( q => this . renderWithQuery ( q ) ) ;
923
994
924
995
let toJoin ;
925
-
926
996
if ( this . options . preAggregationQuery ) {
927
997
const allRegular = regularMeasures . concat (
928
998
cumulativeMeasures
@@ -1153,7 +1223,6 @@ export class BaseQuery {
1153
1223
1154
1224
const multipliedMeasures = measuresToRender ( true , false ) ( measureToHierarchy ) ;
1155
1225
const regularMeasures = measuresToRender ( false , false ) ( measureToHierarchy ) ;
1156
-
1157
1226
const cumulativeMeasures =
1158
1227
R . pipe (
1159
1228
R . map ( multiplied => R . xprod ( [ multiplied ] , measuresToRender ( multiplied , true ) ( measureToHierarchy ) ) ) ,
@@ -3228,7 +3297,7 @@ export class BaseQuery {
3228
3297
}
3229
3298
3230
3299
newSubQueryForCube ( cube , options ) {
3231
- options = { ...options , useNativeSqlPlanner : false } ; // We don't use tesseract for pre-aggregations generation yet
3300
+ options = { ...options } ;
3232
3301
if ( this . options . queryFactory ) {
3233
3302
// When dealing with rollup joins, it's crucial to use the correct parameter allocator for the specific cube in use.
3234
3303
// By default, we'll use BaseQuery, but it's important to note that different databases (Oracle, PostgreSQL, MySQL, Druid, etc.)
0 commit comments