@@ -42,7 +42,7 @@ export class BigqueryQuery extends BaseQuery {
42
42
}
43
43
44
44
public convertTz ( field ) {
45
- return `DATETIME(${ this . timeStampCast ( field ) } , '${ this . timezone } ')` ;
45
+ return `TIMESTAMP( DATETIME(${ field } ) , '${ this . timezone } ')` ;
46
46
}
47
47
48
48
public timeStampCast ( value ) {
@@ -58,7 +58,7 @@ export class BigqueryQuery extends BaseQuery {
58
58
}
59
59
60
60
public timeGroupedColumn ( granularity , dimension ) {
61
- return `DATETIME_TRUNC(${ dimension } , ${ GRANULARITY_TO_INTERVAL [ granularity ] } )` ;
61
+ return this . timeStampCast ( `DATETIME_TRUNC(${ dimension } , ${ GRANULARITY_TO_INTERVAL [ granularity ] } )` ) ;
62
62
}
63
63
64
64
/**
@@ -72,7 +72,7 @@ export class BigqueryQuery extends BaseQuery {
72
72
73
73
return `(${ this . dateTimeCast ( `'${ origin } '` ) } + INTERVAL ${ intervalFormatted } *
74
74
CAST(FLOOR(
75
- DATETIME_DIFF(${ source } , ${ this . dateTimeCast ( `'${ origin } '` ) } , ${ timeUnit } ) /
75
+ DATETIME_DIFF(${ this . dateTimeCast ( source ) } , ${ this . dateTimeCast ( `'${ origin } '` ) } , ${ timeUnit } ) /
76
76
DATETIME_DIFF(${ beginOfTime } + INTERVAL ${ intervalFormatted } , ${ beginOfTime } , ${ timeUnit } )
77
77
) AS INT64))` ;
78
78
}
@@ -182,31 +182,31 @@ export class BigqueryQuery extends BaseQuery {
182
182
}
183
183
184
184
public subtractInterval ( date , interval ) {
185
- return `DATETIME_SUB(${ date } , INTERVAL ${ this . formatInterval ( interval ) [ 0 ] } )` ;
186
- }
187
-
188
- public addInterval ( date , interval ) {
189
- return `DATETIME_ADD(${ date } , INTERVAL ${ this . formatInterval ( interval ) [ 0 ] } )` ;
190
- }
191
-
192
- public subtractTimestampInterval ( date , interval ) {
193
185
const [ intervalFormatted , timeUnit ] = this . formatInterval ( interval ) ;
194
- if ( [ 'YEAR' , 'MONTH' , 'QUARTER' ] . includes ( timeUnit ) ) {
186
+ if ( [ 'YEAR' , 'MONTH' , 'QUARTER' ] . includes ( timeUnit ) || intervalFormatted . includes ( 'WEEK' ) ) {
195
187
return this . timeStampCast ( `DATETIME_SUB(DATETIME(${ date } ), INTERVAL ${ intervalFormatted } )` ) ;
196
188
}
197
189
198
190
return `TIMESTAMP_SUB(${ date } , INTERVAL ${ intervalFormatted } )` ;
199
191
}
200
192
201
- public addTimestampInterval ( date , interval ) {
193
+ public addInterval ( date , interval ) {
202
194
const [ intervalFormatted , timeUnit ] = this . formatInterval ( interval ) ;
203
- if ( [ 'YEAR' , 'MONTH' , 'QUARTER' ] . includes ( timeUnit ) ) {
195
+ if ( [ 'YEAR' , 'MONTH' , 'QUARTER' ] . includes ( timeUnit ) || intervalFormatted . includes ( 'WEEK' ) ) {
204
196
return this . timeStampCast ( `DATETIME_ADD(DATETIME(${ date } ), INTERVAL ${ intervalFormatted } )` ) ;
205
197
}
206
198
207
199
return `TIMESTAMP_ADD(${ date } , INTERVAL ${ intervalFormatted } )` ;
208
200
}
209
201
202
+ public subtractTimestampInterval ( timestamp , interval ) {
203
+ return this . subtractInterval ( timestamp , interval ) ;
204
+ }
205
+
206
+ public addTimestampInterval ( timestamp , interval ) {
207
+ return this . addInterval ( timestamp , interval ) ;
208
+ }
209
+
210
210
public nowTimestampSql ( ) {
211
211
return 'CURRENT_TIMESTAMP()' ;
212
212
}
@@ -215,6 +215,90 @@ export class BigqueryQuery extends BaseQuery {
215
215
return `UNIX_SECONDS(${ this . nowTimestampSql ( ) } )` ;
216
216
}
217
217
218
+ /**
219
+ * Should be protected, but BaseQuery is in js
220
+ * Overridden from BaseQuery to support BigQuery strict data types for
221
+ * joining conditions (note timeStampCast)
222
+ */
223
+ public override runningTotalDateJoinCondition ( ) {
224
+ return this . timeDimensions
225
+ . map (
226
+ d => [
227
+ d ,
228
+ ( _dateFrom : string , dateTo : string , dateField : string , dimensionDateFrom : string , _dimensionDateTo : string ) => `${ dateField } >= ${ dimensionDateFrom } AND ${ dateField } <= ${ this . timeStampCast ( dateTo ) } `
229
+ ]
230
+ ) ;
231
+ }
232
+
233
+ /**
234
+ * Should be protected, but BaseQuery is in js
235
+ * Overridden from BaseQuery to support BigQuery strict data types for
236
+ * joining conditions (note timeStampCast)
237
+ */
238
+ public override rollingWindowToDateJoinCondition ( granularity ) {
239
+ return this . timeDimensions
240
+ . filter ( td => td . granularity )
241
+ . map (
242
+ d => [
243
+ d ,
244
+ ( dateFrom : string , dateTo : string , dateField : string , _dimensionDateFrom : string , _dimensionDateTo : string , _isFromStartToEnd : boolean ) => `${ dateField } >= ${ this . timeGroupedColumn ( granularity , dateFrom ) } AND ${ dateField } <= ${ this . timeStampCast ( dateTo ) } `
245
+ ]
246
+ ) ;
247
+ }
248
+
249
+ /**
250
+ * Should be protected, but BaseQuery is in js
251
+ * Overridden from BaseQuery to support BigQuery strict data types for
252
+ * joining conditions (note timeStampCast)
253
+ */
254
+ public override rollingWindowDateJoinCondition ( trailingInterval , leadingInterval , offset ) {
255
+ offset = offset || 'end' ;
256
+ return this . timeDimensions
257
+ . filter ( td => td . granularity )
258
+ . map (
259
+ d => [ d , ( dateFrom : string , dateTo : string , dateField : string , _dimensionDateFrom : string , _dimensionDateTo : string , isFromStartToEnd : boolean ) => {
260
+ // dateFrom based window
261
+ const conditions : string [ ] = [ ] ;
262
+ if ( trailingInterval !== 'unbounded' ) {
263
+ const startDate = isFromStartToEnd || offset === 'start' ? dateFrom : dateTo ;
264
+ const trailingStart = trailingInterval ? this . subtractInterval ( startDate , trailingInterval ) : startDate ;
265
+ const sign = offset === 'start' ? '>=' : '>' ;
266
+ conditions . push ( `${ dateField } ${ sign } ${ this . timeStampCast ( trailingStart ) } ` ) ;
267
+ }
268
+ if ( leadingInterval !== 'unbounded' ) {
269
+ const endDate = isFromStartToEnd || offset === 'end' ? dateTo : dateFrom ;
270
+ const leadingEnd = leadingInterval ? this . addInterval ( endDate , leadingInterval ) : endDate ;
271
+ const sign = offset === 'end' ? '<=' : '<' ;
272
+ conditions . push ( `${ dateField } ${ sign } ${ this . timeStampCast ( leadingEnd ) } ` ) ;
273
+ }
274
+ return conditions . length ? conditions . join ( ' AND ' ) : '1 = 1' ;
275
+ } ]
276
+ ) ;
277
+ }
278
+
279
+ // Should be protected, but BaseQuery is in js
280
+ public override dateFromStartToEndConditionSql ( dateJoinCondition , fromRollup , isFromStartToEnd ) {
281
+ return dateJoinCondition . map (
282
+ ( [ d , f ] ) => ( {
283
+ filterToWhere : ( ) => {
284
+ const timeSeries = d . timeSeries ( ) ;
285
+ return f (
286
+ isFromStartToEnd ?
287
+ this . timeStampCast ( this . paramAllocator . allocateParam ( timeSeries [ 0 ] [ 0 ] ) ) :
288
+ `${ this . timeStampInClientTz ( d . dateFromParam ( ) ) } ` ,
289
+ isFromStartToEnd ?
290
+ this . timeStampCast ( this . paramAllocator . allocateParam ( timeSeries [ timeSeries . length - 1 ] [ 1 ] ) ) :
291
+ `${ this . timeStampInClientTz ( d . dateToParam ( ) ) } ` ,
292
+ `${ fromRollup ? this . dimensionSql ( d ) : d . convertedToTz ( ) } ` ,
293
+ `${ this . timeStampInClientTz ( d . dateFromParam ( ) ) } ` ,
294
+ `${ this . timeStampInClientTz ( d . dateToParam ( ) ) } ` ,
295
+ isFromStartToEnd
296
+ ) ;
297
+ }
298
+ } )
299
+ ) ;
300
+ }
301
+
218
302
// eslint-disable-next-line no-unused-vars
219
303
public preAggregationLoadSql ( cube , preAggregation , tableName ) {
220
304
return this . preAggregationSql ( cube , preAggregation ) ;
@@ -250,7 +334,7 @@ export class BigqueryQuery extends BaseQuery {
250
334
const templates = super . sqlTemplates ( ) ;
251
335
templates . quotes . identifiers = '`' ;
252
336
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 %})' ;
337
+ templates . functions . DATETRUNC = 'TIMESTAMP( DATETIME_TRUNC(CAST({{ args[1] }} AS DATETIME), {% if date_part|upper == \'WEEK\' %}{{ \'WEEK(MONDAY)\' }}{% else %}{{ date_part }}{% endif %}) )' ;
254
338
templates . functions . LOG = 'LOG({{ args_concat }}{% if args[1] is undefined %}, 10{% endif %})' ;
255
339
templates . functions . BTRIM = 'TRIM({{ args_concat }})' ;
256
340
templates . functions . STRPOS = 'STRPOS({{ args_concat }})' ;
@@ -263,7 +347,8 @@ export class BigqueryQuery extends BaseQuery {
263
347
templates . expressions . binary = '{% if op == \'%\' %}MOD({{ left }}, {{ right }}){% else %}({{ left }} {{ op }} {{ right }}){% endif %}' ;
264
348
templates . expressions . interval = 'INTERVAL {{ interval }}' ;
265
349
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 }}\'))' ;
350
+ templates . expressions . timestamp_literal = 'TIMESTAMP(\'{{ value }}\')' ;
351
+ templates . expressions . rolling_window_expr_timestamp_cast = 'TIMESTAMP({{ value }})' ;
267
352
delete templates . expressions . ilike ;
268
353
delete templates . expressions . like_escape ;
269
354
templates . filters . like_pattern = 'CONCAT({% if start_wild %}\'%\'{% else %}\'\'{% endif %}, LOWER({{ value }}), {% if end_wild %}\'%\'{% else %}\'\'{% endif %})' ;
0 commit comments