@@ -23,10 +23,24 @@ class PreAggregations {
23
23
if ( preAggregationForQuery ) {
24
24
if ( preAggregationForQuery . preAggregation . useOriginalSqlPreAggregations ) {
25
25
const { preAggregations, result } =
26
- this . collectOriginalSqlPreAggregations ( ( ) =>
27
- this . preAggregationDescriptionsFor ( preAggregationForQuery . cube , preAggregationForQuery )
26
+ this . collectOriginalSqlPreAggregations (
27
+ ( ) => this . preAggregationDescriptionsFor ( preAggregationForQuery . cube , preAggregationForQuery )
28
28
) ;
29
- return R . unnest ( preAggregations . map ( p => this . preAggregationDescriptionsFor ( p . cube , p ) ) ) . concat ( result ) ;
29
+
30
+ const queryForEval = this . query . preAggregationQueryForSqlEvaluation (
31
+ preAggregationForQuery . cube ,
32
+ preAggregationForQuery . preAggregation
33
+ ) ;
34
+
35
+ // TODO consider recursive pre-aggregation descriptions instead of duplication of sub query logic
36
+ return R . unnest ( preAggregations . map (
37
+ p => this . preAggregationDescriptionsFor ( p . cube , p ) . concat (
38
+ R . unnest (
39
+ queryForEval . subQueryDimensions . map ( d => queryForEval . subQueryDescription ( d ) . subQuery )
40
+ . map ( q => q . preAggregations . preAggregationDescriptionsFor ( p . cube , p ) )
41
+ )
42
+ )
43
+ ) ) . concat ( result ) ;
30
44
}
31
45
return this . preAggregationDescriptionsFor ( preAggregationForQuery . cube , preAggregationForQuery ) ;
32
46
}
@@ -44,20 +58,30 @@ class PreAggregations {
44
58
}
45
59
46
60
preAggregationCubes ( ) {
47
- const join = this . query . join ;
61
+ const { join } = this . query ;
48
62
return join . joins . map ( j => j . originalTo ) . concat ( [ join . root ] ) ;
49
63
}
50
64
51
65
preAggregationDescriptionsFor ( cube , foundPreAggregation ) {
52
- if ( foundPreAggregation . preAggregation . partitionGranularity && this . query . timeDimensions . length ) {
66
+ if ( this . canPartitionsBeUsed ( foundPreAggregation ) ) {
53
67
const { dimension, partitionDimension } = this . partitionDimension ( foundPreAggregation ) ;
54
- return partitionDimension . timeSeries ( ) . map ( range =>
55
- this . preAggregationDescriptionFor ( cube , this . addPartitionRangeTo ( foundPreAggregation , dimension , range ) )
68
+ return partitionDimension . timeSeries ( ) . map (
69
+ range => this . preAggregationDescriptionFor (
70
+ cube , this . addPartitionRangeTo ( foundPreAggregation , dimension , range )
71
+ )
56
72
) ;
57
73
}
58
74
return [ this . preAggregationDescriptionFor ( cube , foundPreAggregation ) ] ;
59
75
}
60
76
77
+ canPartitionsBeUsed ( foundPreAggregation ) {
78
+ return foundPreAggregation . preAggregation . partitionGranularity &&
79
+ this . query . timeDimensions . length &&
80
+ foundPreAggregation . references . timeDimensions &&
81
+ foundPreAggregation . references . timeDimensions . length &&
82
+ this . query . timeDimensions . find ( td => td . dimension === foundPreAggregation . references . timeDimensions [ 0 ] . dimension ) ;
83
+ }
84
+
61
85
addPartitionRangeTo ( foundPreAggregation , dimension , range ) {
62
86
return Object . assign ( { } , foundPreAggregation , {
63
87
preAggregation : Object . assign ( { } , foundPreAggregation . preAggregation , {
@@ -70,7 +94,7 @@ class PreAggregations {
70
94
}
71
95
72
96
partitionDimension ( foundPreAggregation ) {
73
- const dimension = this . query . timeDimensions [ 0 ] . dimension ;
97
+ const { dimension } = this . query . timeDimensions [ 0 ] ;
74
98
const partitionDimension = this . query . newTimeDimension ( {
75
99
dimension,
76
100
granularity : this . castGranularity ( foundPreAggregation . preAggregation . partitionGranularity ) ,
@@ -124,14 +148,16 @@ class PreAggregations {
124
148
const preAggregates = this . query . cubeEvaluator . preAggregationsForCube ( cube ) ;
125
149
const originalSqlPreAggregations = R . pipe (
126
150
R . toPairs ,
151
+ // eslint-disable-next-line no-unused-vars
127
152
R . filter ( ( [ k , a ] ) => a . type === 'originalSql' )
128
153
) ( preAggregates ) ;
129
154
if ( originalSqlPreAggregations . length ) {
130
155
const [ preAggregationName , preAggregation ] = originalSqlPreAggregations [ 0 ] ;
131
156
return {
132
157
preAggregationName,
133
158
preAggregation,
134
- cube
159
+ cube,
160
+ references : this . evaluateAllReferences ( cube , preAggregation )
135
161
} ;
136
162
}
137
163
return null ;
@@ -198,11 +224,9 @@ class PreAggregations {
198
224
199
225
canUsePreAggregationAndCheckIfRefValid ( query ) {
200
226
const transformedQuery = PreAggregations . transformQueryToCanUseForm ( query ) ;
201
- return ( refs ) => {
202
- return PreAggregations . canUsePreAggregationForTransformedQueryFn (
203
- transformedQuery , refs
204
- ) ;
205
- } ;
227
+ return ( refs ) => PreAggregations . canUsePreAggregationForTransformedQueryFn (
228
+ transformedQuery , refs
229
+ ) ;
206
230
}
207
231
208
232
checkAutoRollupPreAggregationValid ( refs ) {
@@ -275,6 +299,7 @@ class PreAggregations {
275
299
) ;
276
300
}
277
301
302
+ // eslint-disable-next-line no-unused-vars
278
303
getCubeLattice ( cube , preAggregationName , preAggregation ) {
279
304
throw new UserError ( 'Auto rollups supported only in Enterprise version' ) ;
280
305
}
@@ -294,6 +319,7 @@ class PreAggregations {
294
319
) {
295
320
return R . pipe (
296
321
R . toPairs ,
322
+ // eslint-disable-next-line no-unused-vars
297
323
R . filter ( ( [ k , a ] ) => a . type === 'autoRollup' ) ,
298
324
R . map ( ( [ preAggregationName , preAggregation ] ) => {
299
325
const cubeLattice = this . getCubeLattice ( cube , preAggregationName , preAggregation ) ;
@@ -305,7 +331,8 @@ class PreAggregations {
305
331
preAggregation
306
332
) ,
307
333
cube,
308
- canUsePreAggregation : true
334
+ canUsePreAggregation : true ,
335
+ references : optimalPreAggregation
309
336
} ;
310
337
} )
311
338
) ( preAggregations ) ;
@@ -339,20 +366,25 @@ class PreAggregations {
339
366
findRollupPreAggregationsForCube ( cube , canUsePreAggregation , preAggregations ) {
340
367
return R . pipe (
341
368
R . toPairs ,
369
+ // eslint-disable-next-line no-unused-vars
342
370
R . filter ( ( [ k , a ] ) => a . type === 'rollup' ) ,
343
- R . map ( ( [ preAggregationName , preAggregation ] ) => ( {
344
- preAggregationName,
345
- preAggregation,
346
- cube,
347
- canUsePreAggregation : canUsePreAggregation ( this . evaluateAllReferences ( cube , preAggregation ) )
348
- } ) )
371
+ R . map ( ( [ preAggregationName , preAggregation ] ) => {
372
+ const references = this . evaluateAllReferences ( cube , preAggregation ) ;
373
+ return {
374
+ preAggregationName,
375
+ preAggregation,
376
+ cube,
377
+ canUsePreAggregation : canUsePreAggregation ( references ) ,
378
+ references
379
+ } ;
380
+ } )
349
381
) ( preAggregations ) ;
350
382
}
351
383
352
384
rollupMatchResultDescriptions ( ) {
353
385
return this . rollupMatchResults ( ) . map ( p => ( {
354
386
...this . preAggregationDescriptionFor ( p . cube , p ) ,
355
- references : this . evaluateAllReferences ( p . cube , p . preAggregation ) ,
387
+ references : p . references ,
356
388
canUsePreAggregation : p . canUsePreAggregation
357
389
} ) ) ;
358
390
}
@@ -382,6 +414,15 @@ class PreAggregations {
382
414
return { preAggregations, result } ;
383
415
}
384
416
417
+ originalSqlPreAggregationQuery ( cube , aggregation ) {
418
+ return this . query . newSubQuery ( {
419
+ rowLimit : null ,
420
+ timeDimensions : aggregation . partitionTimeDimensions ,
421
+ preAggregationQuery : true ,
422
+ collectOriginalSqlPreAggregations : this . query . safeEvaluateSymbolContext ( ) . collectOriginalSqlPreAggregations
423
+ } ) ;
424
+ }
425
+
385
426
rollupPreAggregationQuery ( cube , aggregation ) {
386
427
const references = this . evaluateAllReferences ( cube , aggregation ) ;
387
428
return this . query . newSubQuery ( {
@@ -421,27 +462,39 @@ class PreAggregations {
421
462
}
422
463
423
464
autoRollupNameSuffix ( cube , aggregation ) {
465
+ // eslint-disable-next-line prefer-template
424
466
return '_' + aggregation . dimensions . concat (
425
467
aggregation . timeDimensions . map ( d => `${ d . dimension } ${ d . granularity . substring ( 0 , 1 ) } ` )
426
468
) . map ( s => {
427
469
const path = s . split ( '.' ) ;
428
470
return `${ path [ 0 ] [ 0 ] } ${ path [ 1 ] } ` ;
429
- } ) . map ( s => s . replace ( / _ / g, '' ) ) . join ( "_" ) . replace ( / [ . ] / g, '' ) . toLowerCase ( ) ;
471
+ } ) . map ( s => s . replace ( / _ / g, '' ) ) . join ( "_" )
472
+ . replace ( / [ . ] / g, '' )
473
+ . toLowerCase ( ) ;
430
474
}
431
475
432
476
evaluateAllReferences ( cube , aggregation ) {
433
477
return this . query . cubeEvaluator . evaluatePreAggregationReferences ( cube , aggregation ) ;
434
478
}
435
479
480
+ originalSqlPreAggregationTable ( preAggregation ) {
481
+ return this . canPartitionsBeUsed ( preAggregation ) ?
482
+ this . partitionUnion ( preAggregation , true ) :
483
+ this . query . preAggregationTableName (
484
+ preAggregation . cube ,
485
+ preAggregation . preAggregationName
486
+ ) ;
487
+ }
488
+
436
489
rollupPreAggregation ( preAggregationForQuery ) {
437
- const table = preAggregationForQuery . preAggregation . partitionGranularity && this . query . timeDimensions . length ?
490
+ const table = this . canPartitionsBeUsed ( preAggregationForQuery ) ?
438
491
this . partitionUnion ( preAggregationForQuery ) :
439
492
this . query . preAggregationTableName (
440
493
preAggregationForQuery . cube ,
441
494
preAggregationForQuery . preAggregationName
442
495
) ;
443
- let segmentFilters = this . query . segments . map ( s =>
444
- this . query . newFilter ( { dimension : s . segment , operator : 'equals' , values : [ true ] } )
496
+ const segmentFilters = this . query . segments . map (
497
+ s => this . query . newFilter ( { dimension : s . segment , operator : 'equals' , values : [ true ] } )
445
498
) ;
446
499
const filters =
447
500
segmentFilters
@@ -465,12 +518,12 @@ class PreAggregations {
465
518
R . fromPairs
466
519
) ( preAggregationForQuery . preAggregation . type === 'autoRollup' ?
467
520
preAggregationForQuery . preAggregation . measures :
468
- this . evaluateAllReferences ( preAggregationForQuery . cube , preAggregationForQuery . preAggregation ) . measures
469
- ) ;
521
+ this . evaluateAllReferences ( preAggregationForQuery . cube , preAggregationForQuery . preAggregation ) . measures ) ;
470
522
471
523
const rollupGranularity = this . castGranularity ( preAggregationForQuery . preAggregation . granularity ) || 'day' ;
472
524
473
525
return this . query . evaluateSymbolSqlWithContext (
526
+ // eslint-disable-next-line prefer-template
474
527
( ) => `SELECT ${ this . query . baseSelect ( ) } FROM ${ table } ${ this . query . baseWhere ( filters ) } ` +
475
528
this . query . groupByClause ( ) +
476
529
this . query . baseHaving ( this . query . measureFilters ) +
@@ -484,7 +537,7 @@ class PreAggregations {
484
537
) ;
485
538
}
486
539
487
- partitionUnion ( preAggregationForQuery ) {
540
+ partitionUnion ( preAggregationForQuery , withoutAlias ) {
488
541
const { dimension, partitionDimension } = this . partitionDimension ( preAggregationForQuery ) ;
489
542
490
543
const union = partitionDimension . timeSeries ( ) . map ( range => {
@@ -495,7 +548,7 @@ class PreAggregations {
495
548
preAggregation . preAggregation
496
549
) ;
497
550
} ) . map ( table => `SELECT * FROM ${ table } ` ) . join ( " UNION ALL " ) ;
498
- return `(${ union } ) as partition_union` ;
551
+ return `(${ union } )${ withoutAlias ? '' : ' as partition_union' } ` ;
499
552
}
500
553
}
501
554
0 commit comments