Skip to content

Commit 6b582f6

Browse files
authored
fix(tesseract): Dimnesions with granularity in group_by + drivers support (#9928)
1 parent 3368ba4 commit 6b582f6

File tree

29 files changed

+1786
-39
lines changed

29 files changed

+1786
-39
lines changed

.github/workflows/drivers-tests.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ jobs:
269269
include:
270270
- database: postgres
271271
use_tesseract_sql_planner: true
272+
- database: snowflake
273+
use_tesseract_sql_planner: true
274+
- database: redshift
275+
use_tesseract_sql_planner: true
272276
- database: bigquery-export-bucket-gcs
273277
use_tesseract_sql_planner: true
274278
- database: athena-export-bucket-s3

packages/cubejs-schema-compiler/src/adapter/RedshiftQuery.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ export class RedshiftQuery extends PostgresQuery {
8585
const templates = super.sqlTemplates();
8686
templates.functions.DLOG10 = 'LOG(10, {{ args_concat }})';
8787
templates.functions.DATEDIFF = 'DATEDIFF({{ date_part }}, {{ args[1] }}, {{ args[2] }})';
88+
templates.statements.time_series_select = 'SELECT dates.f::timestamp date_from, dates.t::timestamp date_to \n' +
89+
'FROM (\n' +
90+
'{% for time_item in seria %}' +
91+
' select \'{{ time_item[0] }}\' f, \'{{ time_item[1] }}\' t \n' +
92+
'{% if not loop.last %} UNION ALL\n{% endif %}' +
93+
'{% endfor %}' +
94+
') AS dates';
95+
delete templates.statements.generated_time_series_select;
96+
delete templates.operators.is_not_distinct_from;
8897
delete templates.functions.COVAR_POP;
8998
delete templates.functions.COVAR_SAMP;
9099
delete templates.window_frame_types.range;

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

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,18 @@ describe('SQL Generation', () => {
302302
type: 'sum',
303303
group_by: [visitors.source]
304304
},
305+
visitors_revenue_per_year: {
306+
multi_stage: true,
307+
sql: \`\${revenue}\`,
308+
type: 'sum',
309+
group_by: [visitors.created_at.year]
310+
},
311+
visitors_revenue_reduce_day: {
312+
multi_stage: true,
313+
sql: \`\${revenue}\`,
314+
type: 'sum',
315+
reduce_by: [visitors.created_at.day]
316+
},
305317
visitors_revenue_without_date: {
306318
multi_stage: true,
307319
sql: \`\${revenue}\`,
@@ -4434,6 +4446,184 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL
44344446
}]
44354447
));
44364448

4449+
if (getEnv('nativeSqlPlanner')) {
4450+
it('multi stage sum with group by time dim with granularity', async () => runQueryTest(
4451+
{
4452+
measures: ['visitors.visitors_revenue_per_year', 'visitors.revenue'],
4453+
dimensions: ['visitors.source'],
4454+
timeDimensions: [{
4455+
dimension: 'visitors.created_at',
4456+
granularity: 'year',
4457+
dateRange: ['2016-01-01', '2017-01-30']
4458+
}],
4459+
timezone: 'America/Los_Angeles',
4460+
order: [{
4461+
id: 'visitors.source'
4462+
}, {
4463+
id: 'visitors.created_at'
4464+
}],
4465+
},
4466+
4467+
[{
4468+
visitors__source: 'google',
4469+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4470+
visitors__visitors_revenue_per_year: '1500',
4471+
visitors__revenue: '300'
4472+
},
4473+
{
4474+
visitors__source: 'some',
4475+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4476+
visitors__visitors_revenue_per_year: '1500',
4477+
visitors__revenue: '300'
4478+
},
4479+
{
4480+
visitors__source: null,
4481+
visitors__created_at_year: '2016-01-01T00:00:00.000Z',
4482+
visitors__visitors_revenue_per_year: '500',
4483+
visitors__revenue: '500'
4484+
},
4485+
{
4486+
visitors__source: null,
4487+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4488+
visitors__visitors_revenue_per_year: '1500',
4489+
visitors__revenue: '900'
4490+
}]
4491+
));
4492+
} else {
4493+
it.skip('multi stage sum with group by time dim with granularity', async () => {
4494+
// Works only in Tesseract
4495+
});
4496+
}
4497+
4498+
if (getEnv('nativeSqlPlanner')) {
4499+
it('multi stage sum multiple time dims group by time dim with granularity', async () => runQueryTest(
4500+
{
4501+
measures: ['visitors.visitors_revenue_per_year', 'visitors.revenue'],
4502+
dimensions: ['visitors.source'],
4503+
timeDimensions: [{
4504+
dimension: 'visitors.created_at',
4505+
granularity: 'year',
4506+
dateRange: ['2014-01-01', '2018-01-30']
4507+
},
4508+
{
4509+
dimension: 'visitors.created_at',
4510+
granularity: 'day',
4511+
dateRange: ['2014-01-01', '2018-01-30']
4512+
}],
4513+
timezone: 'America/Los_Angeles',
4514+
order: [{
4515+
id: 'visitors.source'
4516+
}, {
4517+
id: 'visitors.created_at'
4518+
}],
4519+
},
4520+
4521+
[
4522+
{
4523+
visitors__source: 'google',
4524+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4525+
visitors__created_at_day: '2017-01-05T00:00:00.000Z',
4526+
visitors__visitors_revenue_per_year: '1500',
4527+
visitors__revenue: '300'
4528+
},
4529+
{
4530+
visitors__source: 'some',
4531+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4532+
visitors__created_at_day: '2017-01-02T00:00:00.000Z',
4533+
visitors__visitors_revenue_per_year: '1500',
4534+
visitors__revenue: '100'
4535+
},
4536+
{
4537+
visitors__source: 'some',
4538+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4539+
visitors__created_at_day: '2017-01-04T00:00:00.000Z',
4540+
visitors__visitors_revenue_per_year: '1500',
4541+
visitors__revenue: '200'
4542+
},
4543+
{
4544+
visitors__source: null,
4545+
visitors__created_at_year: '2016-01-01T00:00:00.000Z',
4546+
visitors__created_at_day: '2016-09-06T00:00:00.000Z',
4547+
visitors__visitors_revenue_per_year: '500',
4548+
visitors__revenue: '500'
4549+
},
4550+
{
4551+
visitors__source: null,
4552+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4553+
visitors__created_at_day: '2017-01-06T00:00:00.000Z',
4554+
visitors__visitors_revenue_per_year: '1500',
4555+
visitors__revenue: '900'
4556+
}
4557+
]
4558+
));
4559+
} else {
4560+
it.skip('multi stage sum multiple time dims group by time dim with granularity', async () => {
4561+
// Works only in Tesseract
4562+
});
4563+
}
4564+
4565+
if (getEnv('nativeSqlPlanner')) {
4566+
it('multi stage sum multiple time dims reduce by time dim with granularity', async () => runQueryTest(
4567+
{
4568+
measures: ['visitors.visitors_revenue_reduce_day', 'visitors.revenue'],
4569+
timeDimensions: [{
4570+
dimension: 'visitors.created_at',
4571+
granularity: 'year',
4572+
dateRange: ['2014-01-01', '2018-01-30']
4573+
},
4574+
{
4575+
dimension: 'visitors.created_at',
4576+
granularity: 'day',
4577+
dateRange: ['2014-01-01', '2018-01-30']
4578+
}],
4579+
timezone: 'America/Los_Angeles',
4580+
order: [{
4581+
id: 'visitors.source'
4582+
}, {
4583+
id: 'visitors.created_at'
4584+
}],
4585+
},
4586+
4587+
[
4588+
4589+
{
4590+
visitors__created_at_year: '2016-01-01T00:00:00.000Z',
4591+
visitors__created_at_day: '2016-09-06T00:00:00.000Z',
4592+
visitors__visitors_revenue_reduce_day: '500',
4593+
visitors__revenue: '500'
4594+
},
4595+
{
4596+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4597+
visitors__created_at_day: '2017-01-02T00:00:00.000Z',
4598+
visitors__visitors_revenue_reduce_day: '1500',
4599+
visitors__revenue: '100'
4600+
},
4601+
{
4602+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4603+
visitors__created_at_day: '2017-01-04T00:00:00.000Z',
4604+
visitors__visitors_revenue_reduce_day: '1500',
4605+
visitors__revenue: '200'
4606+
},
4607+
{
4608+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4609+
visitors__created_at_day: '2017-01-05T00:00:00.000Z',
4610+
visitors__visitors_revenue_reduce_day: '1500',
4611+
visitors__revenue: '300'
4612+
},
4613+
{
4614+
visitors__created_at_year: '2017-01-01T00:00:00.000Z',
4615+
visitors__created_at_day: '2017-01-06T00:00:00.000Z',
4616+
visitors__visitors_revenue_reduce_day: '1500',
4617+
visitors__revenue: '900'
4618+
}
4619+
]
4620+
));
4621+
} else {
4622+
it.skip('multi stage sum multiple time dims reduce by time dim with granularity', async () => {
4623+
// Works only in Tesseract
4624+
});
4625+
}
4626+
44374627
if (getEnv('nativeSqlPlanner')) {
44384628
it('multi stage sum with group by over view', async () => runQueryTest(
44394629
{

packages/cubejs-testing-drivers/fixtures/_schemas.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,13 @@
424424
"type": "prior"
425425
}]
426426
},
427+
{
428+
"name": "totalProfitForQuarter",
429+
"type": "sum",
430+
"sql": "{totalProfit}",
431+
"multi_stage": true,
432+
"group_by": ["orderDate.quarter"]
433+
},
427434
{
428435
"name": "totalProfitForStatus",
429436
"type": "sum",

packages/cubejs-testing-drivers/fixtures/athena.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
158158
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
159159
"Tesseract: SQL API: Timeshift measure from cube",
160+
"querying BigECommerce: multi-stage group by time dimension",
160161

161162
"---------------------------------------",
162163
"Custom Granularities ",
@@ -191,6 +192,7 @@
191192
"querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
192193
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
193194
"SQL API: Timeshift measure from cube",
195+
"querying BigECommerce: multi-stage group by time dimension",
194196

195197
"querying BigECommerce: rolling window by 2 week",
196198
"querying custom granularities ECommerce: count by three_months_by_march + no dimension",

packages/cubejs-testing-drivers/fixtures/bigquery.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
172172
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
173173
"Tesseract: SQL API: Timeshift measure from cube",
174+
"querying BigECommerce: multi-stage group by time dimension",
174175

175176
"---------------------------------------",
176177
"SKIPPED SQL API (Need work)",
@@ -223,6 +224,7 @@
223224
"querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
224225
"querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
225226
"SQL API: Timeshift measure from cube",
227+
"querying BigECommerce: multi-stage group by time dimension",
226228

227229
"---- Different results comparing to baseQuery version. Need to investigate ----",
228230
"SQL API: SQL push down push to cube quoted alias",

packages/cubejs-testing-drivers/fixtures/clickhouse.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
209209
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
210210
"Tesseract: SQL API: Timeshift measure from cube",
211+
"querying BigECommerce: multi-stage group by time dimension",
211212

212213
"---------------------------------------",
213214
"Custom Granularities ",

packages/cubejs-testing-drivers/fixtures/databricks-jdbc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@
224224
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
225225
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
226226
"Tesseract: SQL API: Timeshift measure from cube",
227+
"querying BigECommerce: multi-stage group by time dimension",
227228

228229
"---------------------------------------",
229230
"Custom Granularities ",

packages/cubejs-testing-drivers/fixtures/mssql.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
151151
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
152152
"Tesseract: SQL API: Timeshift measure from cube",
153+
"querying BigECommerce: multi-stage group by time dimension",
153154

154155
"---------------------------------------",
155156
"SKIPPED SQL API (Need work)",

packages/cubejs-testing-drivers/fixtures/mysql.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailMonthAgo",
147147
"Tesseract: querying BigECommerce with Retail Calendar: totalCountRetailWeekAgo",
148148
"Tesseract: SQL API: Timeshift measure from cube",
149+
"querying BigECommerce: multi-stage group by time dimension",
149150

150151
"---------------------------------------",
151152
"Custom Granularities ",

0 commit comments

Comments
 (0)