@@ -47,6 +47,38 @@ export class BigQueryDatasource {
4747 return [ strInterval , shift ] ;
4848 }
4949
50+ public static _extractFromClause ( sql ) {
51+ let str = sql . replace ( / \n / g, " " ) ;
52+ const from = str . search ( / f r o m / i) ;
53+ str = str . substring ( from + 4 ) . trim ( ) ;
54+ const last = str . search ( " " ) ;
55+ return str . substring ( 1 , last - 1 ) ;
56+ }
57+
58+ public static _FindTimeField ( sql , timeFields ) {
59+ const select = sql . search ( / s e l e c t / i) ;
60+ const from = sql . search ( / f r o m / i) ;
61+ const fields = sql . substring ( select + 6 , from ) ;
62+ const splitFrom = fields . split ( "," ) ;
63+ let col ;
64+ for ( let i = 0 ; i < splitFrom . length ; i ++ ) {
65+ let field = splitFrom [ i ] . search ( / A S / i) ;
66+ if ( field === - 1 ) {
67+ field = splitFrom [ i ] . length ;
68+ }
69+ col = splitFrom [ i ]
70+ . substring ( 0 , field )
71+ . trim ( )
72+ . replace ( "`" , "" )
73+ . replace ( "`" , "" ) ;
74+ for ( const fl of timeFields ) {
75+ if ( fl . text === col ) {
76+ return fl ;
77+ }
78+ }
79+ }
80+ return null ;
81+ }
5082 private static _handleError ( error ) {
5183 if ( error . cancelled === true ) {
5284 return [ ] ;
@@ -238,35 +270,54 @@ export class BigQueryDatasource {
238270 queries . push ( newQuery ) ;
239271 }
240272 } ) ;
273+ let modOptions ;
241274 const allQueryPromise = _ . map ( queries , query => {
242275 const tmpQ = this . queryModel . target . rawSql ;
243- this . queryModel . target . metricColumn = query . metricColumn ;
244- this . queryModel . target . partitioned = query . partitioned ;
245- this . queryModel . target . partitionedField = query . partitionedField ;
246- this . queryModel . target . rawSql = query . rawSql ;
247- this . queryModel . target . sharded = query . sharded ;
248- this . queryModel . target . table = query . table ;
249- this . queryModel . target . timeColumn = query . timeColumn ;
250- this . queryModel . target . timeColumnType = query . timeColumnType ;
251- const modOptions = BigQueryDatasource . _setupTimeShiftQuery (
252- query ,
253- options
254- ) ;
255- let q = this . queryModel . expend_macros ( modOptions ) ;
256- q = BigQueryDatasource . _updatePartition ( q , modOptions ) ;
257- q = BigQueryDatasource . _updateTableSuffix ( q , modOptions ) ;
258- if ( query . refId . search ( Shifted ) > - 1 ) {
259- q = this . _updateAlias ( q , modOptions , query . refId ) ;
260- }
261- const limit = q . match ( / [ ^ ] + ( \b L I M I T \b ) / gi) ;
262- if ( limit == null ) {
263- q += " LIMIT " + options . maxDataPoints ;
276+ if ( this . queryModel . target . rawQuery === false ) {
277+ this . queryModel . target . metricColumn = query . metricColumn ;
278+ this . queryModel . target . partitioned = query . partitioned ;
279+ this . queryModel . target . partitionedField = query . partitionedField ;
280+ this . queryModel . target . rawSql = query . rawSql ;
281+ this . queryModel . target . sharded = query . sharded ;
282+ this . queryModel . target . table = query . table ;
283+ this . queryModel . target . timeColumn = query . timeColumn ;
284+ this . queryModel . target . timeColumnType = query . timeColumnType ;
285+ modOptions = BigQueryDatasource . _setupTimeShiftQuery ( query , options ) ;
286+ const q = this . setUpQ ( modOptions , options , query ) ;
287+ console . log ( q ) ;
288+ this . queryModel . target . rawSql = tmpQ ;
289+ return this . doQuery ( q , options . panelId + query . refId ) . then ( response => {
290+ return ResponseParser . parseDataQuery ( response , query . format ) ;
291+ } ) ;
292+ } else {
293+ // Fix raw sql
294+ const from = BigQueryDatasource . _extractFromClause ( tmpQ ) ;
295+ const splitFrom = from . split ( "." ) ;
296+ const project = splitFrom [ 0 ] ;
297+ const dataset = splitFrom [ 1 ] ;
298+ const table = splitFrom [ 2 ] ;
299+ this . getDateFields ( project , dataset , table )
300+ . then ( dateFields => {
301+ const tm = BigQueryDatasource . _FindTimeField ( tmpQ , dateFields ) ;
302+ this . queryModel . target . rawSql = query . rawSql ;
303+ this . queryModel . target . timeColumn = tm . text ;
304+ this . queryModel . target . timeColumnType = tm . value ;
305+ this . queryModel . target . table = table ;
306+ } )
307+ . catch ( err => {
308+ console . log ( err ) ;
309+ } ) ;
310+ modOptions = BigQueryDatasource . _setupTimeShiftQuery (
311+ query ,
312+ options
313+ ) ;
314+ const q = this . setUpQ ( modOptions , options , query ) ;
315+ console . log ( q ) ;
316+ return this . doQuery ( q , options . panelId + query . refId ) . then (
317+ response => {
318+ return ResponseParser . parseDataQuery ( response , query . format ) ;
319+ } ) ;
264320 }
265- console . log ( q ) ;
266- this . queryModel . target . rawSql = tmpQ ;
267- return this . doQuery ( q , options . panelId + query . refId ) . then ( response => {
268- return ResponseParser . parseDataQuery ( response , query . format ) ;
269- } ) ;
270321 } ) ;
271322 return this . $q . all ( allQueryPromise ) . then ( ( responses ) : any => {
272323 const data = [ ] ;
@@ -393,6 +444,17 @@ export class BigQueryDatasource {
393444 return ResponseParser . parseTableFields ( data , filter ) ;
394445 }
395446
447+ public async getDateFields (
448+ projectName : string ,
449+ datasetName : string ,
450+ tableName : string
451+ ) {
452+ return this . getTableFields ( projectName , datasetName , tableName , [
453+ "DATE" ,
454+ "TIMESTAMP" ,
455+ "DATETIME"
456+ ] ) ;
457+ }
396458 public async getDefaultProject ( ) {
397459 try {
398460 if ( this . authenticationType === "gce" || ! this . projectName ) {
@@ -447,7 +509,19 @@ export class BigQueryDatasource {
447509 this . responseParser . transformAnnotationResponse ( options , data )
448510 ) ;
449511 }
450-
512+ private setUpQ ( modOptions , options , query ) {
513+ let q = this . queryModel . expend_macros ( modOptions ) ;
514+ q = BigQueryDatasource . _updatePartition ( q , modOptions ) ;
515+ q = BigQueryDatasource . _updateTableSuffix ( q , modOptions ) ;
516+ if ( query . refId . search ( Shifted ) > - 1 ) {
517+ q = this . _updateAlias ( q , modOptions , query . refId ) ;
518+ }
519+ const limit = q . match ( / [ ^ ] + ( \b L I M I T \b ) / gi) ;
520+ if ( limit == null ) {
521+ q += " LIMIT " + options . maxDataPoints ;
522+ }
523+ return q ;
524+ }
451525 private async doRequest ( url , requestId = "requestId" , maxRetries = 3 ) {
452526 return this . backendSrv
453527 . datasourceRequest ( {
@@ -511,7 +585,6 @@ export class BigQueryDatasource {
511585 return BigQueryDatasource . _handleError ( error ) ;
512586 } ) ;
513587 }
514-
515588 private async _waitForJobComplete ( queryResults , requestId , jobId ) {
516589 let sleepTimeMs = 100 ;
517590 console . log ( "New job id: " , jobId ) ;
0 commit comments