Skip to content

Commit 9c51dfb

Browse files
committed
fix join conditions date time datatypes comparisons for BQ
1 parent 0493052 commit 9c51dfb

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,8 +1788,12 @@ export class BaseQuery {
17881788
const dateJoinConditionSql =
17891789
dateJoinCondition.map(
17901790
([d, f]) => f(
1791-
`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_from')}`,
1792-
`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_to')}`,
1791+
// Time-series table is generated differently in different dialects,
1792+
// but some dialects (like BigQuery) require strict date types and can not automatically convert
1793+
// between date and timestamp for comparisons, at the same time, time dimensions are expected to be
1794+
// timestamps, so we need to align types for join conditions/comparisons.
1795+
this.timeStampCast(`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_from')}`),
1796+
this.timeStampCast(`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_to')}`),
17931797
`${baseQueryAlias}.${d.aliasName()}`,
17941798
`'${d.dateFromFormatted()}'`,
17951799
`'${d.dateToFormatted()}'`
@@ -1822,9 +1826,10 @@ export class BaseQuery {
18221826
.join(', ');
18231827
}
18241828

1829+
// BigQuery has strict date type and can not automatically convert between date
1830+
// and timestamp, so we override dateFromStartToEndConditionSql() in BigQuery Dialect
18251831
dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, isFromStartToEnd) {
18261832
return dateJoinCondition.map(
1827-
// TODO these weird conversions to be strict typed for big query.
18281833
// TODO Consider adding strict definitions of local and UTC time type
18291834
([d, f]) => ({
18301835
filterToWhere: () => {

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,29 @@ export class BigqueryQuery extends BaseQuery {
215215
return `UNIX_SECONDS(${this.nowTimestampSql()})`;
216216
}
217217

218+
// Should be protected, but BaseQuery is in js
219+
public override dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, isFromStartToEnd) {
220+
return dateJoinCondition.map(
221+
([d, f]) => ({
222+
filterToWhere: () => {
223+
const timeSeries = d.timeSeries();
224+
return f(
225+
isFromStartToEnd ?
226+
this.timeStampCast(this.paramAllocator.allocateParam(timeSeries[0][0])) :
227+
`${this.timeStampInClientTz(d.dateFromParam())}`,
228+
isFromStartToEnd ?
229+
this.timeStampCast(this.paramAllocator.allocateParam(timeSeries[timeSeries.length - 1][1])) :
230+
`${this.timeStampInClientTz(d.dateToParam())}`,
231+
`${fromRollup ? this.dimensionSql(d) : d.convertedToTz()}`,
232+
`${this.timeStampInClientTz(d.dateFromParam())}`,
233+
`${this.timeStampInClientTz(d.dateToParam())}`,
234+
isFromStartToEnd
235+
);
236+
}
237+
})
238+
);
239+
}
240+
218241
// eslint-disable-next-line no-unused-vars
219242
public preAggregationLoadSql(cube, preAggregation, tableName) {
220243
return this.preAggregationSql(cube, preAggregation);
@@ -250,7 +273,7 @@ export class BigqueryQuery extends BaseQuery {
250273
const templates = super.sqlTemplates();
251274
templates.quotes.identifiers = '`';
252275
templates.quotes.escape = '\\`';
253-
templates.functions.DATETRUNC = 'DATETIME_TRUNC(CAST({{ args[1] }} AS DATETIME), {% if date_part|upper == \'WEEK\' %}{{ \'WEEK(MONDAY)\' }}{% else %}{{ date_part }}{% endif %})';
276+
templates.functions.DATETRUNC = 'TIMESTAMP(DATETIME_TRUNC(CAST({{ args[1] }} AS DATETIME), {% if date_part|upper == \'WEEK\' %}{{ \'WEEK(MONDAY)\' }}{% else %}{{ date_part }}{% endif %}))';
254277
templates.functions.LOG = 'LOG({{ args_concat }}{% if args[1] is undefined %}, 10{% endif %})';
255278
templates.functions.BTRIM = 'TRIM({{ args_concat }})';
256279
templates.functions.STRPOS = 'STRPOS({{ args_concat }})';
@@ -263,7 +286,7 @@ export class BigqueryQuery extends BaseQuery {
263286
templates.expressions.binary = '{% if op == \'%\' %}MOD({{ left }}, {{ right }}){% else %}({{ left }} {{ op }} {{ right }}){% endif %}';
264287
templates.expressions.interval = 'INTERVAL {{ interval }}';
265288
templates.expressions.extract = 'EXTRACT({% if date_part == \'DOW\' %}DAYOFWEEK{% elif date_part == \'DOY\' %}DAYOFYEAR{% else %}{{ date_part }}{% endif %} FROM {{ expr }})';
266-
templates.expressions.timestamp_literal = 'DATETIME(TIMESTAMP(\'{{ value }}\'))';
289+
templates.expressions.timestamp_literal = 'TIMESTAMP(\'{{ value }}\')';
267290
delete templates.expressions.ilike;
268291
delete templates.expressions.like_escape;
269292
templates.filters.like_pattern = 'CONCAT({% if start_wild %}\'%\'{% else %}\'\'{% endif %}, LOWER({{ value }}), {% if end_wild %}\'%\'{% else %}\'\'{% endif %})';

0 commit comments

Comments
 (0)