Skip to content

Commit ce20f2c

Browse files
committed
should work
1 parent c96a2b4 commit ce20f2c

File tree

9 files changed

+66
-41
lines changed

9 files changed

+66
-41
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,8 @@ export class BaseQuery {
10781078
* @returns {string}
10791079
*/
10801080
subtractInterval(date, interval) {
1081-
return `${date} - interval '${interval}'`;
1081+
const intervalStr = this.intervalString(interval);
1082+
return `${date} - interval ${intervalStr}`;
10821083
}
10831084

10841085
/**
@@ -1087,7 +1088,17 @@ export class BaseQuery {
10871088
* @returns {string}
10881089
*/
10891090
addInterval(date, interval) {
1090-
return `${date} + interval '${interval}'`;
1091+
const intervalStr = this.intervalString(interval);
1092+
return `${date} + interval ${intervalStr}`;
1093+
}
1094+
1095+
/**
1096+
* @param {string} interval
1097+
* @returns {string}
1098+
*/
1099+
intervalString(interval) {
1100+
return `'${interval}'`;
1101+
10911102
}
10921103

10931104
/**
@@ -4111,6 +4122,7 @@ export class BaseQuery {
41114122
},
41124123
tesseract: {
41134124
ilike: '{{ expr }} {% if negated %}NOT {% endif %}ILIKE {{ pattern }}', // May require different overloads in Tesseract than the ilike from expressions used in SQLAPI.
4125+
series_bounds_cast: '{{ expr }}'
41144126
},
41154127
filters: {
41164128
equals: '{{ column }} = {{ value }}{{ is_null_check }}',

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ export class BigqueryQuery extends BaseQuery {
203203
return this.subtractInterval(timestamp, interval);
204204
}
205205

206+
public intervalString(interval: string): string {
207+
return `${interval}`;
208+
}
209+
206210
public addTimestampInterval(timestamp, interval) {
207211
return this.addInterval(timestamp, interval);
208212
}
@@ -353,6 +357,7 @@ export class BigqueryQuery extends BaseQuery {
353357
delete templates.expressions.like_escape;
354358
templates.filters.like_pattern = 'CONCAT({% if start_wild %}\'%\'{% else %}\'\'{% endif %}, LOWER({{ value }}), {% if end_wild %}\'%\'{% else %}\'\'{% endif %})';
355359
templates.tesseract.ilike = 'LOWER({{ expr }}) {% if negated %}NOT {% endif %} LIKE {{ pattern }}';
360+
templates.tesseract.series_bounds_cast = 'TIMESTAMP({{ expr }})';
356361
templates.types.boolean = 'BOOL';
357362
templates.types.float = 'FLOAT64';
358363
templates.types.double = 'FLOAT64';

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ export class PostgresQuery extends BaseQuery {
8383
templates.types.binary = 'BYTEA';
8484
templates.operators.is_not_distinct_from = 'IS NOT DISTINCT FROM';
8585
templates.statements.generated_time_series_select = 'SELECT d AS "date_from",\n' +
86-
'd + interval \'{{ granularity }}\' - interval \'1 millisecond\' AS "date_to" \n' +
86+
'd + interval {{ granularity }} - interval \'1 millisecond\' AS "date_to" \n' +
8787
'FROM generate_series({{ start }}::timestamp, {{ end }}:: timestamp, \'{{ granularity }}\'::interval) d ';
8888
templates.statements.generated_time_series_with_cte_range_source = 'SELECT d AS "date_from",\n' +
89-
'd + interval \'{{ granularity }}\' - interval \'1 millisecond\' AS "date_to" \n' +
89+
'd + interval {{ granularity }} - interval \'1 millisecond\' AS "date_to" \n' +
9090
'FROM {{ range_source }}, LATERAL generate_series({{ range_source }}.{{ min_name }}, {{ range_source }}.{{ max_name }}, \'{{ granularity }}\'::interval) d ';
9191
return templates;
9292
}

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,9 @@ export class PrestodbQuery extends BaseQuery {
8484
return `date_trunc('${GRANULARITY_TO_INTERVAL[granularity]}', ${dimension})`;
8585
}
8686

87-
public subtractInterval(date, interval) {
87+
public intervalString(interval: string): string {
8888
const [intervalValue, intervalUnit] = interval.split(' ');
89-
return `${date} - interval '${intervalValue}' ${intervalUnit}`;
90-
}
91-
92-
public addInterval(date, interval) {
93-
const [intervalValue, intervalUnit] = interval.split(' ');
94-
return `${date} + interval '${intervalValue}' ${intervalUnit}`;
89+
return `'${intervalValue}' ${intervalUnit}`;
9590
}
9691

9792
public seriesSql(timeDimension) {
@@ -160,6 +155,25 @@ export class PrestodbQuery extends BaseQuery {
160155
// Presto intervals have a YearMonth or DayTime type variants, but no universal type
161156
delete templates.types.interval;
162157
templates.types.binary = 'VARBINARY';
158+
templates.tesseract.ilike = 'LOWER({{ expr }}) {% if negated %}NOT {% endif %} LIKE {{ pattern }}';
159+
templates.filters.like_pattern = 'CONCAT({% if start_wild %}\'%\'{% else %}\'\'{% endif %}, LOWER({{ value }}), {% if end_wild %}\'%\'{% else %}\'\'{% endif %}) ESCAPE \'\\\'';
160+
templates.statements.time_series_select = 'SELECT from_iso8601_timestamp(dates.f) date_from, from_iso8601_timestamp(dates.t) date_to \n' +
161+
'FROM (\n' +
162+
'{% for time_item in seria %}' +
163+
' select \'{{ time_item[0] }}\' f, \'{{ time_item[1] }}\' t \n' +
164+
'{% if not loop.last %} UNION ALL\n{% endif %}' +
165+
'{% endfor %}' +
166+
') AS dates';
167+
templates.statements.generated_time_series_select = 'SELECT d AS date_from,\n' +
168+
'date_add(\'MILLISECOND\', -1, d + interval {{ granularity }}) AS date_to\n' +
169+
'FROM UNNEST(\n' +
170+
'SEQUENCE(CAST(from_iso8601_timestamp({{ start }}) AS TIMESTAMP), CAST(from_iso8601_timestamp({{ end }}) AS TIMESTAMP), INTERVAL {{ granularity }})\n' +
171+
') AS dates(d)';
172+
templates.statements.generated_time_series_with_cte_range_source = 'SELECT d AS date_from,\n' +
173+
'date_add(\'MILLISECOND\', -1, d + interval {{ granularity }}) AS date_to\n' +
174+
'FROM {{ range_source }} CROSS JOIN UNNEST(\n' +
175+
'SEQUENCE(CAST({{ range_source }}.{{ min_name }} AS TIMESTAMP), CAST({{ range_source }}.{{ max_name }} AS TIMESTAMP), INTERVAL {{ granularity }})\n' +
176+
') AS dates(d)';
163177
return templates;
164178
}
165179

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

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,9 @@
176176
"SQL API: Extended nested Rollup over asterisk"
177177
],
178178
"tesseractSkip": [
179-
"---------------------------------------",
180-
"Core tests ",
181-
"---------------------------------------",
182179
"for the ECommerce.TimeAnalysisExternal",
183180
"for the ECommerce.TimeAnalysisInternal",
184181

185-
"---------------------------------------",
186-
"Full tests ",
187-
"---------------------------------------",
188-
189-
"---------------------------------------",
190-
"SKIPPED FOR ALL ",
191-
"---------------------------------------",
192182
"querying Products: dimensions -- doesn't work wo ordering",
193183
"querying ECommerce: total quantity, avg discount, total sales, total profit by product + order + total -- rounding in athena",
194184
"querying ECommerce: total sales, total profit by month + order (date) + total -- doesn't work with the BigQuery",
@@ -198,34 +188,27 @@
198188
"querying BigECommerce: null boolean",
199189
"--------------------",
200190

201-
"---------------------------------------",
202-
"Requires Tesseract. ",
203-
"---------------------------------------",
204-
"querying BigECommerce: rolling window by 2 day without date range",
205-
"querying BigECommerce: rolling window by 2 month without date range",
206-
"querying BigECommerce: rolling window YTD",
207-
"querying BigECommerce: rolling window YTD without date range",
208-
"--------------------",
209191

210-
"week granularity is not supported for intervals",
211-
"--------------------",
212192
"querying BigECommerce: rolling window by 2 week",
213-
214-
"---------------------------------------",
215-
"Custom Granularities ",
216-
"---------------------------------------",
217193
"querying custom granularities ECommerce: count by three_months_by_march + no dimension",
218194
"querying custom granularities ECommerce: count by three_months_by_march + dimension",
219-
220-
"SKIPPED SQL API (Need work)",
221-
"---------------------------------------",
195+
"querying custom granularities (with preaggregation) ECommerce: totalQuantity by half_year + no dimension",
196+
"querying custom granularities (with preaggregation) ECommerce: totalQuantity by half_year + dimension",
197+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByUnbounded",
198+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByTrailing",
199+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading",
200+
"pre-aggregations Customers: running total without time dimension",
201+
"querying BigECommerce: totalProfitYearAgo",
202+
"SQL API: post-aggregate percentage of total",
222203
"SQL API: Simple Rollup",
223204
"SQL API: Complex Rollup",
224205
"SQL API: Nested Rollup",
225206
"SQL API: Rollup with aliases",
226207
"SQL API: Rollup over exprs",
227208
"SQL API: Nested Rollup with aliases",
228209
"SQL API: Nested Rollup over asterisk",
229-
"SQL API: Extended nested Rollup over asterisk"
210+
"SQL API: Extended nested Rollup over asterisk",
211+
"SQL API: Timeshift measure from cube",
212+
"SQL API: SQL push down push to cube quoted alias"
230213
]
231214
}

rust/cubesqlplanner/cubesqlplanner/src/cube_bridge/driver_tools.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub trait DriverTools {
2424
fn get_allocated_params(&self) -> Result<Vec<String>, CubeError>;
2525
fn subtract_interval(&self, date: String, interval: String) -> Result<String, CubeError>;
2626
fn add_interval(&self, date: String, interval: String) -> Result<String, CubeError>;
27+
fn interval_string(&self, interval: String) -> Result<String, CubeError>;
2728
fn add_timestamp_interval(&self, date: String, interval: String) -> Result<String, CubeError>;
2829
fn interval_and_minimal_time_unit(&self, interval: String) -> Result<Vec<String>, CubeError>;
2930
fn hll_init(&self, sql: String) -> Result<String, CubeError>;

rust/cubesqlplanner/cubesqlplanner/src/plan/time_series.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl TimeSeries {
5151
));
5252
}
5353
let interval = interval_description[0].clone();
54+
let interval = templates.interval_string(interval)?;
5455
let minimal_time_unit = interval_description[1].clone();
5556
match &self.date_range {
5657
TimeSeriesDateRange::Filter(from_date, to_date) => {

rust/cubesqlplanner/cubesqlplanner/src/planner/filter/base_filter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,8 @@ impl BaseFilter {
397397
) -> Result<(String, String), CubeError> {
398398
let from_expr = format!("min({})", plan_templates.quote_identifier("date_from")?);
399399
let to_expr = format!("max({})", plan_templates.quote_identifier("date_to")?);
400-
let from_expr = plan_templates.time_stamp_cast(from_expr)?;
401-
let to_expr = plan_templates.time_stamp_cast(to_expr)?;
400+
let from_expr = plan_templates.series_bounds_cast(&from_expr)?;
401+
let to_expr = plan_templates.series_bounds_cast(&to_expr)?;
402402
let alias = format!("value");
403403
let time_series_cte_name = format!("time_series"); // FIXME May be should be passed as parameter
404404

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ impl PlanSqlTemplates {
8686
self.driver_tools.add_interval(date, interval)
8787
}
8888

89+
pub fn interval_string(&self, interval: String) -> Result<String, CubeError> {
90+
self.driver_tools.interval_string(interval)
91+
}
92+
8993
pub fn add_timestamp_interval(
9094
&self,
9195
date: String,
@@ -669,6 +673,11 @@ impl PlanSqlTemplates {
669673
)
670674
}
671675

676+
pub fn series_bounds_cast(&self, expr: &str) -> Result<String, CubeError> {
677+
self.render
678+
.render_template(&"tesseract/series_bounds_cast", context! { expr => expr })
679+
}
680+
672681
pub fn additional_null_check(&self, need: bool, column: &String) -> Result<String, CubeError> {
673682
if need {
674683
self.or_is_null_check(column.clone())

0 commit comments

Comments
 (0)