Skip to content
This repository was archived by the owner on Dec 11, 2022. It is now read-only.

Commit c96e554

Browse files
committed
Fixes #216
Support macros in hand written sql
1 parent 85e573f commit c96e554

File tree

5 files changed

+62428
-60
lines changed

5 files changed

+62428
-60
lines changed

dist/module.js

Lines changed: 62323 additions & 23 deletions
Large diffs are not rendered by default.

dist/module.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bigquery_query.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -620,18 +620,17 @@ export default class BigQueryQuery {
620620
return q;
621621
}
622622
}
623-
624623
public replaceTimeFilters(q, options) {
625624
let fromD = options.range.from;
626625
let toD = options.range.to;
627626
if (this.target.convertToUTC === true) {
628627
fromD = new Date(
629628
options.range.from._d.getTime() +
630-
options.range.from._d.getTimezoneOffset() * 60000
629+
options.range.from._d.getTimezoneOffset() * 60000
631630
);
632631
toD = new Date(
633632
options.range.to._d.getTime() +
634-
options.range.to._d.getTimezoneOffset() * 60000
633+
options.range.to._d.getTimezoneOffset() * 60000
635634
);
636635
}
637636
let to = "";

src/datasource.ts

Lines changed: 101 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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(/from/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(/select/i);
60+
const from = sql.search(/from/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(/ AS /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(/[^]+(\bLIMIT\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(/[^]+(\bLIMIT\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);

src/query_ctrl.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ export class BigQueryQueryCtrl extends QueryCtrl {
224224
};
225225
this.selectMenu.push(hyperloglog);
226226

227-
228227
this.selectMenu.push({ text: "Alias", value: "alias" });
229228
this.selectMenu.push({ text: "Column", value: "column" });
230229
this.selectMenu.push({ text: "Time Shift", value: "timeshift" });
@@ -478,10 +477,7 @@ export class BigQueryQueryCtrl extends QueryCtrl {
478477
}
479478

480479
public findTimeShiftIndex(selectParts) {
481-
return _.findIndex(
482-
selectParts,
483-
(p: any) => p.def.type === "timeshift"
484-
);
480+
return _.findIndex(selectParts, (p: any) => p.def.type === "timeshift");
485481
}
486482
public applySegment(dst, src) {
487483
dst.value = src.value;

0 commit comments

Comments
 (0)