diff --git a/public/app/plugins/datasource/postgres/partials/query.editor.html b/public/app/plugins/datasource/postgres/partials/query.editor.html index 3d3b7c43388..58d2415479a 100644 --- a/public/app/plugins/datasource/postgres/partials/query.editor.html +++ b/public/app/plugins/datasource/postgres/partials/query.editor.html @@ -46,7 +46,7 @@
diff --git a/public/app/plugins/datasource/postgres/postgres_query.ts b/public/app/plugins/datasource/postgres/postgres_query.ts index a6f45dbcee8..eb51449dd39 100644 --- a/public/app/plugins/datasource/postgres/postgres_query.ts +++ b/public/app/plugins/datasource/postgres/postgres_query.ts @@ -135,7 +135,7 @@ export default class PostgresQuery { query = columnName.params[0]; 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 (special) { @@ -155,9 +155,13 @@ export default class PostgresQuery { } let over = overParts.join(' '); + let curr: string; + let prev: string; switch (special.params[0]) { 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; case 'rate': let timeColumn = this.target.timeColumn; @@ -165,11 +169,14 @@ export default class PostgresQuery { timeColumn = 'min(' + timeColumn + ')'; } - let curr = query; - let prev = 'lag(' + curr + ') OVER (' + over + ')'; + curr = query; + prev = 'lag(' + curr + ') OVER (' + over + ')'; query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))'; break; + default: + query = special.params[0] + '(' + query + ') OVER (' + over + ')'; + break; } } diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index 62bd1c63fab..88ef587037d 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -99,8 +99,28 @@ export class PostgresQueryCtrl extends QueryCtrl { buildSelectMenu() { 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: '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 }); + if (subItem) { + partModel.params = [subItem.value]; + } let addAlias = false; switch (item.value) { @@ -223,7 +246,7 @@ export class PostgresQueryCtrl extends QueryCtrl { if (this.target.group.length === 0) { this.addGroup('time', '1m'); } - case 'special': + case 'window': let index = _.findIndex(selectParts, (p: any) => p.def.type === item.value); if (index !== -1) { selectParts[index] = partModel; diff --git a/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts b/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts index 00ac5ed0e56..c589eb3c43c 100644 --- a/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts +++ b/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts @@ -61,9 +61,11 @@ describe('PostgresQuery', function() { column = [ { type: 'column', params: ['v'] }, { 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() { @@ -83,17 +85,20 @@ describe('PostgresQuery', function() { column = [ { type: 'column', params: ['v'] }, { 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 = [ { type: 'column', params: ['v'] }, { type: 'alias', params: ['a'] }, { type: 'aggregate', params: ['max'] }, - { type: 'special', params: ['increase'] }, + { type: 'window', params: ['increase'] }, ]; 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"' ); }); diff --git a/public/app/plugins/datasource/postgres/sql_part.ts b/public/app/plugins/datasource/postgres/sql_part.ts index b0265a645ed..487ddb50276 100644 --- a/public/app/plugins/datasource/postgres/sql_part.ts +++ b/public/app/plugins/datasource/postgres/sql_part.ts @@ -76,13 +76,13 @@ register({ }); register({ - type: 'special', + type: 'window', style: 'label', params: [ { name: 'function', type: 'string', - options: ['increase', 'rate'], + options: ['increase', 'rate', 'sum'], }, ], defaultParams: ['increase'],