@@ -3,6 +3,7 @@ import { prepareJsCompiler } from '../../unit/PrepareCompiler';
33import { DataSchemaCompiler } from '../../../src/compiler/DataSchemaCompiler' ;
44import { JoinGraph } from '../../../src/compiler/JoinGraph' ;
55import { CubeEvaluator } from '../../../src/compiler/CubeEvaluator' ;
6+ import { testWithPreAggregation } from './pre-aggregation-utils' ;
67
78describe ( 'Multiple join paths' , ( ) => {
89 jest . setTimeout ( 200000 ) ;
@@ -20,7 +21,8 @@ describe('Multiple join paths', () => {
2021 // └-->F-------┘
2122 // View, pre-aggregations and all interesting parts should use ADEX path
2223 // It should NOT be the shortest one from A to X (that's AFX), nor first in join edges declaration (that's ABCX)
23- // All join conditions would be essentially `FALSE`, but with different syntax, to be able to test SQL generation
24+ // All join conditions would be essentially `TRUE` for ADEX joins and `FALSE` for everything else
25+ // But they would use different syntax, to be able to test SQL generation
2426 // Also, there should be only one way to cover cubes A and D with joins: A->D join
2527
2628 // TODO in this model queries like [A.a_id, X.x_id] become ambiguous, probably we want to handle this better
@@ -37,7 +39,7 @@ describe('Multiple join paths', () => {
3739 },
3840 D: {
3941 relationship: 'many_to_one',
40- sql: "'A' = 'D'",
42+ sql: "'A' = 'D' OR TRUE ",
4143 },
4244 F: {
4345 relationship: 'many_to_one',
@@ -78,7 +80,6 @@ describe('Multiple join paths', () => {
7880 a_id,
7981 A.D.d_id,
8082 A.D.d_name_for_join_paths,
81- // D.d_id,
8283 A.D.E.X.x_id,
8384 ],
8485 measures: [
@@ -93,6 +94,19 @@ describe('Multiple join paths', () => {
9394 granularity: 'day',
9495 },
9596
97+ adex_cumulative_with_join_paths: {
98+ type: 'rollup',
99+ dimensions: [
100+ a_id,
101+ A.D.E.X.x_id,
102+ ],
103+ measures: [
104+ A.D.E.X.x_cumulative_sum,
105+ ],
106+ timeDimension: A.D.E.X.x_time,
107+ granularity: 'day',
108+ },
109+
96110 ad_without_join_paths: {
97111 type: 'rollup',
98112 dimensions: [
@@ -183,7 +197,7 @@ describe('Multiple join paths', () => {
183197 joins: {
184198 E: {
185199 relationship: 'many_to_one',
186- sql: "'D' = 'E'",
200+ sql: "'D' = 'E' OR TRUE ",
187201 },
188202 },
189203
@@ -228,7 +242,7 @@ describe('Multiple join paths', () => {
228242 joins: {
229243 X: {
230244 relationship: 'many_to_one',
231- sql: "'E' = 'X'",
245+ sql: "'E' = 'X' OR TRUE ",
232246 },
233247 },
234248
@@ -319,6 +333,13 @@ describe('Multiple join paths', () => {
319333 sql: 'x_value',
320334 type: 'sum',
321335 },
336+ x_cumulative_sum: {
337+ sql: 'x_value',
338+ type: 'sum',
339+ rolling_window: {
340+ trailing: 'unbounded',
341+ },
342+ },
322343 },
323344
324345 segments: {
@@ -515,33 +536,108 @@ describe('Multiple join paths', () => {
515536 expect ( preAggregation ) . toBeDefined ( ) ;
516537 } ) ;
517538
518- const preAggregationIds = [
519- 'A.adex_with_join_paths' ,
520- 'A.ad_without_join_paths' ,
539+ function makeReferenceQueryFor ( preAggregationId : string , withDateRange : boolean = false ) : PostgresQuery {
540+ const preAggregations = cubeEvaluator . preAggregations ( {
541+ preAggregationIds : [ preAggregationId ]
542+ } ) ;
543+
544+ expect ( preAggregations . length ) . toBe ( 1 ) ;
545+ const preAggregation = preAggregations [ 0 ] ;
546+
547+ if ( withDateRange ) {
548+ preAggregation . references . timeDimensions = preAggregation . references . timeDimensions . map ( td => ( {
549+ ...td ,
550+ dateRange : [ '1970-01-01' , '1970-01-02' ] ,
551+ } ) ) ;
552+ }
553+
554+ return new PostgresQuery ( { joinGraph, cubeEvaluator, compiler } , {
555+ ...preAggregation . references ,
556+ preAggregationId : preAggregation . id ,
557+ preAggregationsSchema : '' ,
558+ timezone : 'UTC' ,
559+ } ) ;
560+ }
561+
562+ const preAggregationTests = [
563+ {
564+ preAggregationId : 'A.adex_with_join_paths' ,
565+ addTimeRange : false ,
566+ expectedData : [
567+ {
568+ a__a_id : 1 ,
569+ a__a_seg : false ,
570+ a__a_sum : '100' ,
571+ d__d_id : 1 ,
572+ d__d_name_for_join_paths : 'foo' ,
573+ d__d_seg : false ,
574+ x__x_id : 1 ,
575+ x__x_seg : false ,
576+ x__x_time_day : '1970-01-01T00:00:00.000Z' ,
577+ } ,
578+ ] ,
579+ } ,
580+ {
581+ preAggregationId : 'A.adex_cumulative_with_join_paths' ,
582+ addTimeRange : true ,
583+ expectedData : [
584+ {
585+ a__a_id : 1 ,
586+ x__x_cumulative_sum : '100' ,
587+ x__x_id : 1 ,
588+ x__x_time_day : '1970-01-01T00:00:00.000Z' ,
589+ } ,
590+ {
591+ a__a_id : 1 ,
592+ x__x_cumulative_sum : '100' ,
593+ x__x_id : 1 ,
594+ x__x_time_day : '1970-01-02T00:00:00.000Z' ,
595+ } ,
596+ ] ,
597+ } ,
598+ {
599+ preAggregationId : 'A.ad_without_join_paths' ,
600+ addTimeRange : false ,
601+ expectedData : [
602+ {
603+ a__a_id : 1 ,
604+ a__a_seg : false ,
605+ a__a_sum : '100' ,
606+ d__d_id : 1 ,
607+ d__d_name_for_no_join_paths : 'foo' ,
608+ d__d_seg : false ,
609+ d__d_time_day : '1970-01-01T00:00:00.000Z' ,
610+ } ,
611+ ] ,
612+ } ,
521613 ] ;
522- for ( const preAggregationId of preAggregationIds ) {
614+ for ( const { preAggregationId, addTimeRange , expectedData } of preAggregationTests ) {
523615 // eslint-disable-next-line no-loop-func
524616 it ( `pre-aggregation ${ preAggregationId } should match its own references` , async ( ) => {
525- const preAggregations = cubeEvaluator . preAggregations ( { } ) ;
617+ // Always not using range, because reference query would have no range to start from
618+ // but should match pre-aggregation anyway
619+ const query = makeReferenceQueryFor ( preAggregationId ) ;
526620
527- const preAggregation = preAggregations
528- . find ( p => p . id === preAggregationId ) ;
529- if ( preAggregation === undefined ) {
530- throw expect ( preAggregation ) . toBeDefined ( ) ;
621+ const preAggregationsDescription : any = query . preAggregations ?. preAggregationsDescription ( ) ;
622+ const preAggregationFromQuery = preAggregationsDescription . find ( p => p . preAggregationId === preAggregationId ) ;
623+ if ( preAggregationFromQuery === undefined ) {
624+ throw expect ( preAggregationFromQuery ) . toBeDefined ( ) ;
531625 }
626+ } ) ;
532627
533- const query = new PostgresQuery ( { joinGraph , cubeEvaluator , compiler } , {
534- ... preAggregation . references ,
535- preAggregationId : preAggregation . id ,
536- } ) ;
628+ // eslint-disable-next-line no-loop-func
629+ it ( `pre-aggregation ${ preAggregationId } reference query should be executable` , async ( ) => {
630+ // Adding date range for rolling window measure
631+ const query = makeReferenceQueryFor ( preAggregationId , addTimeRange ) ;
537632
538633 const preAggregationsDescription : any = query . preAggregations ?. preAggregationsDescription ( ) ;
539- const preAggregationFromQuery = preAggregationsDescription . find ( p => p . preAggregationId === preAggregation . id ) ;
634+ const preAggregationFromQuery = preAggregationsDescription . find ( p => p . preAggregationId === preAggregationId ) ;
540635 if ( preAggregationFromQuery === undefined ) {
541636 throw expect ( preAggregationFromQuery ) . toBeDefined ( ) ;
542637 }
543638
544- expect ( preAggregationFromQuery . preAggregationId ) . toBe ( preAggregationId ) ;
639+ const res = await testWithPreAggregation ( preAggregationFromQuery , query ) ;
640+ expect ( res ) . toEqual ( expectedData ) ;
545641 } ) ;
546642 }
547643 } ) ;
0 commit comments