Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,18 @@ describe('SQL Generation', () => {
type: 'sum',
group_by: []
},
visitors_revenue_per_source: {
multi_stage: true,
sql: \`\${revenue}\`,
type: 'sum',
group_by: [visitors.source]
},
visitors_revenue_without_date: {
multi_stage: true,
sql: \`\${revenue}\`,
type: 'sum',
reduce_by: [visitors.created_at]
},
percentage_of_total: {
multi_stage: true,
sql: \`(100 * \${revenue} / NULLIF(\${visitors_revenue_total}, 0))::int\`,
Expand Down Expand Up @@ -887,7 +899,6 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL
async function runQueryTest(q, expectedResult) {
await compiler.compile();
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, q);

const res = await dbRunner.testQuery(query.buildSqlAndParams());
console.log(JSON.stringify(res));

Expand Down Expand Up @@ -3759,6 +3770,186 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL
}]
));

it('multi stage sum with group by', async () => runQueryTest(
{
measures: ['visitors.visitors_revenue_per_source', 'visitors.revenue'],
dimensions: ['visitors.source', 'visitors.created_at'],
order: [{
id: 'visitors.source'
}, {
id: 'visitors.created_at'
}],
},
[{
visitors__source: 'google',
visitors__created_at: '2017-01-06T00:00:00.000Z',
visitors__visitors_revenue_per_source: '300',
visitors__revenue: '300'
},
{
visitors__source: 'some',
visitors__created_at: '2017-01-03T00:00:00.000Z',
visitors__visitors_revenue_per_source: '300',
visitors__revenue: '100'
},
{
visitors__source: 'some',
visitors__created_at: '2017-01-05T00:00:00.000Z',
visitors__visitors_revenue_per_source: '300',
visitors__revenue: '200'
},
{
visitors__source: null,
visitors__created_at: '2016-09-07T00:00:00.000Z',
visitors__visitors_revenue_per_source: '1400',
visitors__revenue: '500'
},
{
visitors__source: null,
visitors__created_at: '2017-01-07T00:00:00.000Z',
visitors__visitors_revenue_per_source: '1400',
visitors__revenue: '900'
}]
));

if (getEnv('nativeSqlPlanner')) {
it('multi stage sum with group by over view', async () => runQueryTest(
{
measures: ['visitors_multi_stage.visitors_revenue_per_source', 'visitors_multi_stage.revenue'],
dimensions: ['visitors_multi_stage.source', 'visitors_multi_stage.created_at'],
order: [{
id: 'visitors_multi_stage.source'
}, {
id: 'visitors_multi_stage.created_at'
}],
},
[{
visitors_multi_stage__source: 'google',
visitors_multi_stage__created_at: '2017-01-06T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_per_source: '300',
visitors_multi_stage__revenue: '300'
},
{
visitors_multi_stage__source: 'some',
visitors_multi_stage__created_at: '2017-01-03T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_per_source: '300',
visitors_multi_stage__revenue: '100'
},
{
visitors_multi_stage__source: 'some',
visitors_multi_stage__created_at: '2017-01-05T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_per_source: '300',
visitors_multi_stage__revenue: '200'
},
{
visitors_multi_stage__source: null,
visitors_multi_stage__created_at: '2016-09-07T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_per_source: '1400',
visitors_multi_stage__revenue: '500'
},
{
visitors_multi_stage__source: null,
visitors_multi_stage__created_at: '2017-01-07T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_per_source: '1400',
visitors_multi_stage__revenue: '900'
}]
));
} else {
it.skip('multi stage sum with reduce by over view', async () => {
// Works only in Tesseract
});
}

it('multi stage sum with reduce by', async () => runQueryTest(
{
measures: ['visitors.visitors_revenue_without_date', 'visitors.revenue'],
dimensions: ['visitors.source', 'visitors.created_at'],
order: [{
id: 'visitors.source'
}, {
id: 'visitors.created_at'
}],
},
[{
visitors__source: 'google',
visitors__created_at: '2017-01-06T00:00:00.000Z',
visitors__visitors_revenue_without_date: '300',
visitors__revenue: '300'
},
{
visitors__source: 'some',
visitors__created_at: '2017-01-03T00:00:00.000Z',
visitors__visitors_revenue_without_date: '300',
visitors__revenue: '100'
},
{
visitors__source: 'some',
visitors__created_at: '2017-01-05T00:00:00.000Z',
visitors__visitors_revenue_without_date: '300',
visitors__revenue: '200'
},
{
visitors__source: null,
visitors__created_at: '2016-09-07T00:00:00.000Z',
visitors__visitors_revenue_without_date: '1400',
visitors__revenue: '500'
},
{
visitors__source: null,
visitors__created_at: '2017-01-07T00:00:00.000Z',
visitors__visitors_revenue_without_date: '1400',
visitors__revenue: '900'
}]
));

if (getEnv('nativeSqlPlanner')) {
it('multi stage sum with reduce by over view', async () => runQueryTest(
{
measures: ['visitors_multi_stage.visitors_revenue_without_date', 'visitors_multi_stage.revenue'],
dimensions: ['visitors_multi_stage.source', 'visitors_multi_stage.created_at'],
order: [{
id: 'visitors_multi_stage.source'
}, {
id: 'visitors_multi_stage.created_at'
}],
},
[{
visitors_multi_stage__source: 'google',
visitors_multi_stage__created_at: '2017-01-06T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_without_date: '300',
visitors_multi_stage__revenue: '300'
},
{
visitors_multi_stage__source: 'some',
visitors_multi_stage__created_at: '2017-01-03T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_without_date: '300',
visitors_multi_stage__revenue: '100'
},
{
visitors_multi_stage__source: 'some',
visitors_multi_stage__created_at: '2017-01-05T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_without_date: '300',
visitors_multi_stage__revenue: '200'
},
{
visitors_multi_stage__source: null,
visitors_multi_stage__created_at: '2016-09-07T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_without_date: '1400',
visitors_multi_stage__revenue: '500'
},
{
visitors_multi_stage__source: null,
visitors_multi_stage__created_at: '2017-01-07T00:00:00.000Z',
visitors_multi_stage__visitors_revenue_without_date: '1400',
visitors_multi_stage__revenue: '900'
}]
));
} else {
it.skip('multi stage sum with reduce by over view', async () => {
// Works only in Tesseract
});
}

it('multiplied sum and count no dimensions through view', async () => runQueryTest(
{
measures: ['visitors_visitors_checkins_view.revenue', 'visitors_visitors_checkins_view.visitor_checkins_count'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,27 +341,15 @@ impl MultiStageMemberQueryPlanner {
let dimensions = if !reduce_by.is_empty() {
dimensions
.into_iter()
.filter(|d| {
if reduce_by.iter().any(|m| d.full_name() == m.full_name()) {
false
} else {
true
}
})
.filter(|d| !reduce_by.iter().any(|m| d.has_member_in_reference_chain(m)))
.collect_vec()
} else {
dimensions
};
let dimensions = if let Some(group_by) = group_by {
dimensions
.into_iter()
.filter(|d| {
if group_by.iter().any(|m| d.full_name() == m.full_name()) {
true
} else {
false
}
})
.filter(|d| group_by.iter().any(|m| d.has_member_in_reference_chain(m)))
.collect_vec()
} else {
dimensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,21 @@ impl MemberSymbol {
current
}

pub fn has_member_in_reference_chain(&self, member: &Rc<MemberSymbol>) -> bool {
if self.full_name() == member.full_name() {
return true;
}

let mut current = self.reference_member();
while let Some(reference) = current {
if reference.full_name() == member.full_name() {
return true;
}
current = reference.reference_member();
}
false
}

pub fn owned_by_cube(&self) -> bool {
match self {
Self::Dimension(d) => d.owned_by_cube(),
Expand Down
Loading