Skip to content

Commit 7219918

Browse files
committed
fix join conditions date time datatypes comparisons for BQ
1 parent c041a8c commit 7219918

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
@@ -1803,8 +1803,12 @@ export class BaseQuery {
18031803
const dateJoinConditionSql =
18041804
dateJoinCondition.map(
18051805
([d, f]) => f(
1806-
`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_from')}`,
1807-
`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_to')}`,
1806+
// Time-series table is generated differently in different dialects,
1807+
// but some dialects (like BigQuery) require strict date types and can not automatically convert
1808+
// between date and timestamp for comparisons, at the same time, time dimensions are expected to be
1809+
// timestamps, so we need to align types for join conditions/comparisons.
1810+
this.timeStampCast(`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_from')}`),
1811+
this.timeStampCast(`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_to')}`),
18081812
`${baseQueryAlias}.${d.aliasName()}`,
18091813
`'${d.dateFromFormatted()}'`,
18101814
`'${d.dateToFormatted()}'`
@@ -1837,9 +1841,10 @@ export class BaseQuery {
18371841
.join(', ');
18381842
}
18391843

1844+
// BigQuery has strict date type and can not automatically convert between date
1845+
// and timestamp, so we override dateFromStartToEndConditionSql() in BigQuery Dialect
18401846
dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, isFromStartToEnd) {
18411847
return dateJoinCondition.map(
1842-
// TODO these weird conversions to be strict typed for big query.
18431848
// TODO Consider adding strict definitions of local and UTC time type
18441849
([d, f]) => ({
18451850
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)