Skip to content

Commit d81c57d

Browse files
authored
feat(tesseract): Rolling window with custom granularities without date range (#9762)
1 parent 05bb520 commit d81c57d

File tree

23 files changed

+181
-61
lines changed

23 files changed

+181
-61
lines changed

packages/cubejs-backend-shared/src/time.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function parseSqlInterval(intervalStr: SqlInterval): ParsedInterval {
104104

105105
for (let i = 0; i < parts.length; i += 2) {
106106
const value = parseInt(parts[i], 10);
107-
const unit = parts[i + 1];
107+
const unit = parts[i + 1].toLowerCase();
108108

109109
// Remove ending 's' (e.g., 'days' -> 'day')
110110
const singularUnit = (unit.endsWith('s') ? unit.slice(0, -1) : unit) as unitOfTime.DurationConstructor;

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,11 @@ export class BaseQuery {
11171117
return `${date} + interval ${intervalStr}`;
11181118
}
11191119

1120+
// For use in Tesseract
1121+
supportGeneratedSeriesForCustomTd() {
1122+
return false;
1123+
}
1124+
11201125
/**
11211126
* @param {string} interval
11221127
* @returns {string}
@@ -2048,7 +2053,6 @@ export class BaseQuery {
20482053
* Returns a tuple: (formatted interval, minimal time unit)
20492054
*/
20502055
intervalAndMinimalTimeUnit(interval) {
2051-
const intervalParsed = parseSqlInterval(interval);
20522056
const minGranularity = this.diffTimeUnitForInterval(interval);
20532057
return [interval, minGranularity];
20542058
}
@@ -4138,7 +4142,6 @@ export class BaseQuery {
41384142
sort: '{{ expr }} {% if asc %}ASC{% else %}DESC{% endif %} NULLS {% if nulls_first %}FIRST{% else %}LAST{% endif %}',
41394143
order_by: '{% if index %} {{ index }} {% else %} {{ expr }} {% endif %} {% if asc %}ASC{% else %}DESC{% endif %}{% if nulls_first %} NULLS FIRST{% endif %}',
41404144
cast: 'CAST({{ expr }} AS {{ data_type }})',
4141-
cast_to_string: 'CAST({{ expr }} AS TEXT)',
41424145
window_function: '{{ fun_call }} OVER ({% if partition_by_concat %}PARTITION BY {{ partition_by_concat }}{% if order_by_concat or window_frame %} {% endif %}{% endif %}{% if order_by_concat %}ORDER BY {{ order_by_concat }}{% if window_frame %} {% endif %}{% endif %}{% if window_frame %}{{ window_frame }}{% endif %})',
41434146
window_frame_bounds: '{{ frame_type }} BETWEEN {{ frame_start }} AND {{ frame_end }}',
41444147
in_list: '{{ expr }} {% if negated %}NOT {% endif %}IN ({{ in_exprs_concat }})',

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ export class BigqueryQuery extends BaseQuery {
127127
return [`'${intervalParsed.hour}:${intervalParsed.minute}:${intervalParsed.second}' HOUR TO SECOND`, 'SECOND'];
128128
} else if (intervalParsed.minute && intervalParsed.second && intKeys === 2) {
129129
return [`'${intervalParsed.minute}:${intervalParsed.second}' MINUTE TO SECOND`, 'SECOND'];
130+
} else if (intervalParsed.millisecond && intKeys === 1) {
131+
return [`'${intervalParsed.millisecond}' MILLISECOND`, 'MILLISECOND'];
130132
}
131133

132-
// No need to support microseconds.
133-
134134
throw new Error(`Cannot transform interval expression "${interval}" to BigQuery dialect`);
135135
}
136136

@@ -367,7 +367,6 @@ export class BigqueryQuery extends BaseQuery {
367367
templates.types.double = 'FLOAT64';
368368
templates.types.decimal = 'BIGDECIMAL({{ precision }},{{ scale }})';
369369
templates.types.binary = 'BYTES';
370-
templates.expressions.cast_to_string = 'CAST({{ expr }} AS STRING)';
371370
templates.operators.is_not_distinct_from = 'IS NOT DISTINCT FROM';
372371
templates.join_types.full = 'FULL';
373372
templates.statements.time_series_select = 'SELECT DATETIME(TIMESTAMP(f)) date_from, DATETIME(TIMESTAMP(t)) date_to \n' +

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export class PostgresQuery extends BaseQuery {
5757
return `round(hll_cardinality(hll_add_agg(hll_hash_any(${sql}))))`;
5858
}
5959

60+
public supportGeneratedSeriesForCustomTd() {
61+
return true;
62+
}
63+
6064
public sqlTemplates() {
6165
const templates = super.sqlTemplates();
6266
// eslint-disable-next-line no-template-curly-in-string
@@ -82,8 +86,8 @@ export class PostgresQuery extends BaseQuery {
8286
templates.types.double = 'DOUBLE PRECISION';
8387
templates.types.binary = 'BYTEA';
8488
templates.operators.is_not_distinct_from = 'IS NOT DISTINCT FROM';
85-
templates.statements.generated_time_series_select = 'SELECT d AS "date_from",\n' +
86-
'd + interval {{ granularity }} - interval \'1 millisecond\' AS "date_to" \n' +
89+
templates.statements.generated_time_series_select = 'SELECT {{ date_from }} AS "date_from",\n' +
90+
'{{ date_to }} AS "date_to" \n' +
8791
'FROM generate_series({{ start }}::timestamp, {{ end }}:: timestamp, {{ granularity }}::interval) d ';
8892
templates.statements.generated_time_series_with_cte_range_source = 'SELECT d AS "date_from",\n' +
8993
'd + interval {{ granularity }} - interval \'1 millisecond\' AS "date_to" \n' +

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export class PrestodbQuery extends BaseQuery {
122122
return `approx_distinct(${sql})`;
123123
}
124124

125+
public supportGeneratedSeriesForCustomTd() {
126+
return true;
127+
}
128+
125129
protected limitOffsetClause(limit, offset) {
126130
const limitClause = limit != null ? ` LIMIT ${limit}` : '';
127131
const offsetClause = offset != null ? ` OFFSET ${offset}` : '';

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
"querying BigECommerce: rolling window YTD without date range",
150150
"week granularity is not supported for intervals",
151151
"querying BigECommerce: rolling window by 2 week",
152+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
152153

153154
"---------------------------------------",
154155
"Custom Granularities ",
@@ -185,9 +186,6 @@
185186
"querying custom granularities ECommerce: count by three_months_by_march + dimension",
186187
"querying custom granularities (with preaggregation) ECommerce: totalQuantity by half_year + no dimension",
187188
"querying custom granularities (with preaggregation) ECommerce: totalQuantity by half_year + dimension",
188-
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByUnbounded",
189-
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByTrailing",
190-
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading",
191189
"pre-aggregations Customers: running total without time dimension",
192190
"querying BigECommerce: totalProfitYearAgo",
193191
"SQL API: post-aggregate percentage of total",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@
163163
"querying BigECommerce: rolling window by 2 day without date range",
164164
"querying BigECommerce: rolling window by 2 month without date range",
165165
"querying BigECommerce: rolling window YTD without date range",
166+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
166167

167168
"---------------------------------------",
168169
"SKIPPED SQL API (Need work)",
@@ -188,6 +189,7 @@
188189
"querying ECommerce: total quantity, avg discount, total sales, total profit by product + order + total -- rounding in athena",
189190
"querying ECommerce: total sales, total profit by month + order (date) + total -- doesn't work with the BigQuery",
190191
"querying ECommerce: total quantity, avg discount, total sales, total profit by product + order + total -- noisy test",
192+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
191193
"querying BigECommerce: null sum",
192194
"querying BigECommerce: null boolean",
193195
"querying BigECommerce: rolling window by 2 day without date range",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
"querying BigECommerce: rolling window by 2 day without date range",
201201
"querying BigECommerce: rolling window by 2 month without date range",
202202
"querying BigECommerce: rolling window YTD without date range",
203+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
203204

204205
"---------------------------------------",
205206
"Custom Granularities ",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@
216216
"querying BigECommerce: rolling window by 2 day without date range",
217217
"querying BigECommerce: rolling window by 2 month without date range",
218218
"querying BigECommerce: rolling window YTD without date range",
219+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
219220

220221
"---------------------------------------",
221222
"Custom Granularities ",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
"querying BigECommerce: rolling window by 2 day without date range",
143143
"querying BigECommerce: rolling window by 2 month without date range",
144144
"querying BigECommerce: rolling window YTD without date range",
145+
"querying custom granularities ECommerce: count by two_mo_by_feb + no dimension + rollingCountByLeading without date range",
145146

146147
"---------------------------------------",
147148
"SKIPPED SQL API (Need work)",

0 commit comments

Comments
 (0)