refactor column function handling

This commit is contained in:
Sven Klemm 2018-07-28 21:30:08 +02:00
parent 6ca7a03975
commit 5327580939
5 changed files with 52 additions and 17 deletions

View File

@ -46,7 +46,7 @@
<div class="gf-form"> <div class="gf-form">
<label class="dropdown" <label class="dropdown"
dropdown-typeahead="ctrl.selectMenu" dropdown-typeahead="ctrl.selectMenu"
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item)"> dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
</label> </label>
</div> </div>

View File

@ -135,7 +135,7 @@ export default class PostgresQuery {
query = columnName.params[0]; query = columnName.params[0];
let aggregate = _.find(column, (g: any) => g.type === 'aggregate'); let aggregate = _.find(column, (g: any) => g.type === 'aggregate');
let special = _.find(column, (g: any) => g.type === 'special'); let special = _.find(column, (g: any) => g.type === 'window');
if (aggregate) { if (aggregate) {
if (special) { if (special) {
@ -155,9 +155,13 @@ export default class PostgresQuery {
} }
let over = overParts.join(' '); let over = overParts.join(' ');
let curr: string;
let prev: string;
switch (special.params[0]) { switch (special.params[0]) {
case 'increase': case 'increase':
query = query + ' - lag(' + query + ') OVER (' + over + ')'; curr = query;
prev = 'lag(' + curr + ') OVER (' + over + ')';
query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)';
break; break;
case 'rate': case 'rate':
let timeColumn = this.target.timeColumn; let timeColumn = this.target.timeColumn;
@ -165,11 +169,14 @@ export default class PostgresQuery {
timeColumn = 'min(' + timeColumn + ')'; timeColumn = 'min(' + timeColumn + ')';
} }
let curr = query; curr = query;
let prev = 'lag(' + curr + ') OVER (' + over + ')'; prev = 'lag(' + curr + ') OVER (' + over + ')';
query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)';
query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))'; query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))';
break; break;
default:
query = special.params[0] + '(' + query + ') OVER (' + over + ')';
break;
} }
} }

View File

@ -99,8 +99,28 @@ export class PostgresQueryCtrl extends QueryCtrl {
buildSelectMenu() { buildSelectMenu() {
this.selectMenu = [ this.selectMenu = [
{ text: 'Aggregate', value: 'aggregate' }, {
{ text: 'Special', value: 'special' }, text: 'Aggregate Functions',
value: 'aggregate',
submenu: [
{ text: 'Average', value: 'avg' },
{ text: 'Count', value: 'count' },
{ text: 'Maximum', value: 'max' },
{ text: 'Minimum', value: 'min' },
{ text: 'Sum', value: 'sum' },
{ text: 'Standard deviation', value: 'stddev' },
{ text: 'Variance', value: 'variance' },
],
},
{
text: 'Window Functions',
value: 'window',
submenu: [
{ text: 'Increase', value: 'increase' },
{ text: 'Rate', value: 'rate' },
{ text: 'Sum', value: 'sum' },
],
},
{ text: 'Alias', value: 'alias' }, { text: 'Alias', value: 'alias' },
{ text: 'Column', value: 'column' }, { text: 'Column', value: 'column' },
]; ];
@ -207,8 +227,11 @@ export class PostgresQueryCtrl extends QueryCtrl {
}; };
} }
addSelectPart(selectParts, item) { addSelectPart(selectParts, item, subItem) {
let partModel = sqlPart.create({ type: item.value }); let partModel = sqlPart.create({ type: item.value });
if (subItem) {
partModel.params = [subItem.value];
}
let addAlias = false; let addAlias = false;
switch (item.value) { switch (item.value) {
@ -223,7 +246,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
if (this.target.group.length === 0) { if (this.target.group.length === 0) {
this.addGroup('time', '1m'); this.addGroup('time', '1m');
} }
case 'special': case 'window':
let index = _.findIndex(selectParts, (p: any) => p.def.type === item.value); let index = _.findIndex(selectParts, (p: any) => p.def.type === item.value);
if (index !== -1) { if (index !== -1) {
selectParts[index] = partModel; selectParts[index] = partModel;

View File

@ -61,9 +61,11 @@ describe('PostgresQuery', function() {
column = [ column = [
{ type: 'column', params: ['v'] }, { type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] }, { type: 'alias', params: ['a'] },
{ type: 'special', params: ['increase'] }, { type: 'window', params: ['increase'] },
]; ];
expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER (ORDER BY time) AS "a"'); expect(query.buildValueColumn(column)).toBe(
'(CASE WHEN v >= lag(v) OVER (ORDER BY time) THEN v - lag(v) OVER (ORDER BY time) ELSE v END) AS "a"'
);
}); });
describe('When generating value column SQL with metric column', function() { describe('When generating value column SQL with metric column', function() {
@ -83,17 +85,20 @@ describe('PostgresQuery', function() {
column = [ column = [
{ type: 'column', params: ['v'] }, { type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] }, { type: 'alias', params: ['a'] },
{ type: 'special', params: ['increase'] }, { type: 'window', params: ['increase'] },
]; ];
expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER (PARTITION BY host ORDER BY time) AS "a"'); expect(query.buildValueColumn(column)).toBe(
'(CASE WHEN v >= lag(v) OVER (PARTITION BY host ORDER BY time) THEN v - lag(v) OVER (PARTITION BY host ORDER BY time) ELSE v END) AS "a"'
);
column = [ column = [
{ type: 'column', params: ['v'] }, { type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] }, { type: 'alias', params: ['a'] },
{ type: 'aggregate', params: ['max'] }, { type: 'aggregate', params: ['max'] },
{ type: 'special', params: ['increase'] }, { type: 'window', params: ['increase'] },
]; ];
expect(query.buildValueColumn(column)).toBe( expect(query.buildValueColumn(column)).toBe(
'max(v ORDER BY time) - lag(max(v ORDER BY time)) OVER (PARTITION BY host) AS "a"' '(CASE WHEN max(v ORDER BY time) >= lag(max(v ORDER BY time)) OVER (PARTITION BY host) ' +
'THEN max(v ORDER BY time) - lag(max(v ORDER BY time)) OVER (PARTITION BY host) ELSE max(v ORDER BY time) END) AS "a"'
); );
}); });

View File

@ -76,13 +76,13 @@ register({
}); });
register({ register({
type: 'special', type: 'window',
style: 'label', style: 'label',
params: [ params: [
{ {
name: 'function', name: 'function',
type: 'string', type: 'string',
options: ['increase', 'rate'], options: ['increase', 'rate', 'sum'],
}, },
], ],
defaultParams: ['increase'], defaultParams: ['increase'],