From 4dbd83fac18a3cc5e59208d396a32538f2ab1a5e Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Wed, 31 Jan 2018 15:32:32 +0100 Subject: [PATCH] add groupby to querybuilder remove unused aggregations --- .../postgres/partials/query.editor.html | 21 +++ .../datasource/postgres/postgres_query.ts | 5 +- .../plugins/datasource/postgres/query_ctrl.ts | 84 ++++++++++ .../plugins/datasource/postgres/query_part.ts | 150 +----------------- 4 files changed, 110 insertions(+), 150 deletions(-) diff --git a/public/app/plugins/datasource/postgres/partials/query.editor.html b/public/app/plugins/datasource/postgres/partials/query.editor.html index 400855cf82f..3e921e1c631 100644 --- a/public/app/plugins/datasource/postgres/partials/query.editor.html +++ b/public/app/plugins/datasource/postgres/partials/query.editor.html @@ -51,6 +51,27 @@ +
+
+ + + + +
+ +
+ +
+ +
+
+
+
+
diff --git a/public/app/plugins/datasource/postgres/postgres_query.ts b/public/app/plugins/datasource/postgres/postgres_query.ts index e6d84306a9b..389ce85aae9 100644 --- a/public/app/plugins/datasource/postgres/postgres_query.ts +++ b/public/app/plugins/datasource/postgres/postgres_query.ts @@ -22,7 +22,7 @@ export default class PostgresQuery { target.alias = ''; target.orderByTime = target.orderByTime || 'ASC'; -// target.groupBy = target.groupBy || [{ type: 'time', params: ['$__interval'] }, { type: 'fill', params: ['null'] }]; + target.groupBy = target.groupBy || [{ type: 'time', params: ['$__interval'] }, { type: 'fill', params: ['null'] }]; target.select = target.select || [[{ type: 'field', params: ['value'] }]]; this.updateProjection(); @@ -92,9 +92,6 @@ export default class PostgresQuery { if (partModel.def.category === categories.Aggregations) { return false; } - if (partModel.def.category === categories.Selectors) { - return false; - } return true; }); }); diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index 4e39105370b..020d8007789 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -29,6 +29,7 @@ export class PostgresQueryCtrl extends QueryCtrl { tableSegment: any; timeColumnSegment: any; selectMenu: any; + groupBySegment: any; /** @ngInject **/ constructor($scope, $injector, private templateSrv, private $q, private uiSegmentSrv) { @@ -59,6 +60,8 @@ export class PostgresQueryCtrl extends QueryCtrl { this.timeColumnSegment = uiSegmentSrv.newSegment(this.target.timeColumn); this.buildSelectMenu(); + this.groupBySegment = this.uiSegmentSrv.newPlusButton(); + this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope); this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope); } @@ -224,6 +227,87 @@ export class PostgresQueryCtrl extends QueryCtrl { } } + handleGroupByPartEvent(part, index, evt) { + switch (evt.name) { + case 'get-param-options': { + var columnQuery = "SELECT column_name FROM information_schema.columns WHERE "; + columnQuery += " table_schema = '" + this.target.schema + "'"; + columnQuery += " AND table_name = '" + this.target.table + "'"; + + return this.datasource + .metricFindQuery(columnQuery) + .then(this.transformToSegments(true)) + .catch(this.handleQueryError.bind(this)); + } + case 'part-param-changed': { + this.panelCtrl.refresh(); + break; + } + case 'action': { + this.queryModel.removeGroupByPart(part, index); + this.panelCtrl.refresh(); + break; + } + case 'get-part-actions': { + return this.$q.when([{ text: 'Remove', value: 'remove-part' }]); + } + } + } + + getGroupByOptions() { + var columnQuery = "SELECT column_name FROM information_schema.columns WHERE "; + columnQuery += " table_schema = '" + this.target.schema + "'"; + columnQuery += " AND table_name = '" + this.target.table + "'"; + + + return this.datasource + .metricFindQuery(columnQuery) + .then(tags => { + var options = []; + if (!this.queryModel.hasFill()) { + options.push(this.uiSegmentSrv.newSegment({ value: 'fill(null)' })); + } + if (!this.target.limit) { + options.push(this.uiSegmentSrv.newSegment({ value: 'LIMIT' })); + } + if (!this.target.slimit) { + options.push(this.uiSegmentSrv.newSegment({ value: 'SLIMIT' })); + } + if (this.target.orderByTime === 'ASC') { + options.push(this.uiSegmentSrv.newSegment({ value: 'ORDER BY time DESC' })); + } + if (!this.queryModel.hasGroupByTime()) { + options.push(this.uiSegmentSrv.newSegment({ value: 'time($interval)' })); + } + for (let tag of tags) { + options.push(this.uiSegmentSrv.newSegment({ value: 'tag(' + tag.text + ')' })); + } + return options; + }) + .catch(this.handleQueryError.bind(this)); + } + + groupByAction() { + switch (this.groupBySegment.value) { + case 'LIMIT': { + this.target.limit = 10; + break; + } + case 'ORDER BY time DESC': { + this.target.orderByTime = 'DESC'; + break; + } + default: { + this.queryModel.addGroupBy(this.groupBySegment.value); + } + } + + var plusButton = this.uiSegmentSrv.newPlusButton(); + this.groupBySegment.value = plusButton.value; + this.groupBySegment.html = plusButton.html; + this.panelCtrl.refresh(); + } + handleQueryError(err) { this.error = err.message || 'Failed to issue metric query'; return []; diff --git a/public/app/plugins/datasource/postgres/query_part.ts b/public/app/plugins/datasource/postgres/query_part.ts index dffea15dbd1..5828515ec06 100644 --- a/public/app/plugins/datasource/postgres/query_part.ts +++ b/public/app/plugins/datasource/postgres/query_part.ts @@ -4,9 +4,6 @@ import { QueryPartDef, QueryPart, functionRenderer, suffixRenderer } from 'app/c var index = []; var categories = { Aggregations: [], - Selectors: [], - Transformations: [], - Predictors: [], Math: [], Aliasing: [], Fields: [], @@ -44,10 +41,6 @@ function replaceAggregationAddStrategy(selectParts, partModel) { selectParts[i] = partModel; return; } - if (part.def.category === categories.Selectors) { - selectParts[i] = partModel; - return; - } } selectParts.splice(1, 0, partModel); @@ -147,34 +140,10 @@ register({ // transformations -register({ - type: 'derivative', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [ - { - name: 'duration', - type: 'interval', - options: ['1s', '10s', '1m', '5m', '10m', '15m', '1h'], - }, - ], - defaultParams: ['10s'], - renderer: functionRenderer, -}); - -register({ - type: 'spread', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - register({ type: 'non_negative_derivative', addStrategy: addTransformationStrategy, - category: categories.Transformations, + category: categories.Aggregations, params: [ { name: 'duration', @@ -186,46 +155,10 @@ register({ renderer: functionRenderer, }); -register({ - type: 'difference', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - -register({ - type: 'non_negative_difference', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - -register({ - type: 'moving_average', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [{ name: 'window', type: 'int', options: [5, 10, 20, 30, 40] }], - defaultParams: [10], - renderer: functionRenderer, -}); - -register({ - type: 'cumulative_sum', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [], - defaultParams: [], - renderer: functionRenderer, -}); - register({ type: 'stddev', addStrategy: addTransformationStrategy, - category: categories.Transformations, + category: categories.Aggregations, params: [], defaultParams: [], renderer: functionRenderer, @@ -259,60 +192,11 @@ register({ renderer: functionRenderer, }); -register({ - type: 'elapsed', - addStrategy: addTransformationStrategy, - category: categories.Transformations, - params: [ - { - name: 'duration', - type: 'interval', - options: ['1s', '10s', '1m', '5m', '10m', '15m', '1h'], - }, - ], - defaultParams: ['10s'], - renderer: functionRenderer, -}); - -// predictions -register({ - type: 'holt_winters', - addStrategy: addTransformationStrategy, - category: categories.Predictors, - params: [ - { name: 'number', type: 'int', options: [5, 10, 20, 30, 40] }, - { name: 'season', type: 'int', options: [0, 1, 2, 5, 10] }, - ], - defaultParams: [10, 2], - renderer: functionRenderer, -}); - -register({ - type: 'holt_winters_with_fit', - addStrategy: addTransformationStrategy, - category: categories.Predictors, - params: [ - { name: 'number', type: 'int', options: [5, 10, 20, 30, 40] }, - { name: 'season', type: 'int', options: [0, 1, 2, 5, 10] }, - ], - defaultParams: [10, 2], - renderer: functionRenderer, -}); - // Selectors -register({ - type: 'bottom', - addStrategy: replaceAggregationAddStrategy, - category: categories.Selectors, - params: [{ name: 'count', type: 'int' }], - defaultParams: [3], - renderer: functionRenderer, -}); - register({ type: 'max', addStrategy: replaceAggregationAddStrategy, - category: categories.Selectors, + category: categories.Aggregations, params: [], defaultParams: [], renderer: functionRenderer, @@ -321,38 +205,12 @@ register({ register({ type: 'min', addStrategy: replaceAggregationAddStrategy, - category: categories.Selectors, + category: categories.Aggregations, params: [], defaultParams: [], renderer: functionRenderer, }); -register({ - type: 'percentile', - addStrategy: replaceAggregationAddStrategy, - category: categories.Selectors, - params: [{ name: 'nth', type: 'int' }], - defaultParams: [95], - renderer: functionRenderer, -}); - -register({ - type: 'top', - addStrategy: replaceAggregationAddStrategy, - category: categories.Selectors, - params: [{ name: 'count', type: 'int' }], - defaultParams: [3], - renderer: functionRenderer, -}); - -register({ - type: 'tag', - category: groupByTimeFunctions, - params: [{ name: 'tag', type: 'string', dynamicLookup: true }], - defaultParams: ['tag'], - renderer: fieldRenderer, -}); - register({ type: 'math', addStrategy: addMathStrategy,