Skip to content

Commit b0b011e

Browse files
authored
fix(tesseract): Prevent duplicate measures in some cases (#10065)
1 parent 6abbdb3 commit b0b011e

File tree

4 files changed

+95
-10
lines changed

4 files changed

+95
-10
lines changed

packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,9 @@ describe('SQL Generation', () => {
588588
}, {
589589
join_path: 'visitors.visitor_checkins',
590590
includes: ['visitor_checkins_count', 'id_sum']
591+
}, {
592+
join_path: 'visitors.visitor_checkins.cards',
593+
includes: ['max_id']
591594
}]
592595
})
593596
@@ -643,6 +646,10 @@ describe('SQL Generation', () => {
643646
measures: {
644647
count: {
645648
type: 'count'
649+
},
650+
max_id: {
651+
type: 'max',
652+
sql: 'id'
646653
}
647654
},
648655
@@ -2314,6 +2321,62 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL
23142321
});
23152322
});
23162323

2324+
it('multiplied subquery measures', async () => {
2325+
await compiler.compile();
2326+
2327+
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
2328+
measures: [
2329+
'visitor_checkins.id_sum',
2330+
'visitor_checkins.revenue_per_checkin',
2331+
'visitors.visitor_revenue'
2332+
],
2333+
dimensions: [
2334+
'visitors.source',
2335+
'visitor_checkins.source'
2336+
],
2337+
timeDimensions: [],
2338+
timezone: 'America/Los_Angeles'
2339+
});
2340+
2341+
console.log(query.buildSqlAndParams());
2342+
2343+
return dbRunner.testQuery(query.buildSqlAndParams()).then(res => {
2344+
console.log(JSON.stringify(res));
2345+
expect(res).toEqual(
2346+
[
2347+
{
2348+
visitors__source: null,
2349+
vc__source: null,
2350+
vc__id_sum: null,
2351+
vc__revenue_per_checkin: null,
2352+
visitors__visitor_revenue: null
2353+
},
2354+
{
2355+
visitors__source: 'some',
2356+
vc__source: null,
2357+
vc__id_sum: '12',
2358+
vc__revenue_per_checkin: '75',
2359+
visitors__visitor_revenue: '300'
2360+
},
2361+
{
2362+
visitors__source: 'google',
2363+
vc__source: null,
2364+
vc__id_sum: '6',
2365+
vc__revenue_per_checkin: null,
2366+
visitors__visitor_revenue: null
2367+
},
2368+
{
2369+
visitors__source: 'some',
2370+
vc__source: 'google',
2371+
vc__id_sum: '3',
2372+
vc__revenue_per_checkin: '100',
2373+
visitors__visitor_revenue: '100'
2374+
}
2375+
]
2376+
);
2377+
});
2378+
});
2379+
23172380
it('having filter', async () => {
23182381
await compiler.compile();
23192382

rust/cubesqlplanner/cubesqlplanner/src/physical_plan_builder/processors/aggregate_multiplied_subquery.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ impl<'a> LogicalNodeProcessor<'a, AggregateMultipliedSubquery>
3232
context,
3333
)?;
3434

35+
if context.dimensions_query {
36+
return Ok(keys_query);
37+
}
38+
3539
let keys_query_alias = format!("keys");
3640

3741
let mut join_builder =

rust/cubesqlplanner/cubesqlplanner/src/physical_plan_builder/processors/keys_sub_query.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,8 @@ impl<'a> LogicalNodeProcessor<'a, KeysSubQuery> for KeysSubQueryProcessor<'a> {
7272
&references_builder,
7373
&mut context_factory,
7474
)?;
75-
for member in keys_subquery
76-
.schema()
77-
.all_dimensions()
78-
.chain(keys_subquery.primary_keys_dimensions().iter())
79-
{
75+
for member in keys_subquery.schema().all_dimensions() {
8076
let alias = member.alias();
81-
/* self.builder.process_calc_group(
82-
member,
83-
&mut context_factory,
84-
&keys_subquery.filter().all_filters(),
85-
)?; */
8677
references_builder.resolve_references_for_member(
8778
member.clone(),
8879
&None,
@@ -91,6 +82,18 @@ impl<'a> LogicalNodeProcessor<'a, KeysSubQuery> for KeysSubQueryProcessor<'a> {
9182
select_builder.add_projection_member(member, Some(alias));
9283
}
9384

85+
if !context.dimensions_query {
86+
for member in keys_subquery.primary_keys_dimensions().iter() {
87+
let alias = member.alias();
88+
references_builder.resolve_references_for_member(
89+
member.clone(),
90+
&None,
91+
context_factory.render_references_mut(),
92+
)?;
93+
select_builder.add_projection_member(member, Some(alias));
94+
}
95+
}
96+
9497
select_builder.set_distinct();
9598
select_builder.set_filter(filter);
9699
let res = Rc::new(select_builder.build(query_tools.clone(), context_factory));

rust/cubesqlplanner/cubesqlplanner/src/planner/query_properties.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,21 @@ impl QueryProperties {
912912
}
913913
}
914914
}
915+
result.multi_stage_measures = result
916+
.multi_stage_measures
917+
.into_iter()
918+
.unique_by(|itm| itm.full_name())
919+
.collect();
920+
result.regular_measures = result
921+
.regular_measures
922+
.into_iter()
923+
.unique_by(|itm| itm.full_name())
924+
.collect();
925+
result.multiplied_measures = result
926+
.multiplied_measures
927+
.into_iter()
928+
.unique_by(|itm| itm.measure.full_name())
929+
.collect();
915930

916931
Ok(result)
917932
}

0 commit comments

Comments
 (0)