Bläddra i källkod

refactor function handling in query builder

Sven Klemm 7 år sedan
förälder
incheckning
412bb6acab

+ 3 - 3
public/app/plugins/datasource/postgres/partials/query.editor.html

@@ -66,7 +66,7 @@
       </div>
 
       <div class="gf-form">
-        <metric-segment segment="ctrl.whereAdd" get-options="ctrl.getWhereOptions()" on-change="ctrl.whereAddAction(part, $index)"></metric-segment>
+        <metric-segment segment="ctrl.whereAdd" get-options="ctrl.getWhereOptions()" on-change="ctrl.addWhereAction(part, $index)"></metric-segment>
       </div>
 
       <div class="gf-form gf-form--grow">
@@ -83,12 +83,12 @@
 
         <sql-part-editor  ng-repeat="part in ctrl.groupParts"
                             part="part" class="gf-form-label sql-part"
-                            handle-event="ctrl.onGroupPartEvent(part, $index, $event)">
+                            handle-event="ctrl.handleGroupPartEvent(part, $index, $event)">
         </sql-part-editor>
       </div>
 
       <div class="gf-form">
-        <metric-segment segment="ctrl.groupAdd" get-options="ctrl.getGroupOptions()" on-change="ctrl.onGroupAction(part, $index)"></metric-segment>
+        <metric-segment segment="ctrl.groupAdd" get-options="ctrl.getGroupOptions()" on-change="ctrl.addGroupAction(part, $index)"></metric-segment>
       </div>
 
       <div class="gf-form gf-form--grow">

+ 12 - 5
public/app/plugins/datasource/postgres/postgres_query.ts

@@ -134,14 +134,21 @@ export default class PostgresQuery {
     let columnName = _.find(column, (g: any) => g.type === 'column');
     query = columnName.params[0];
 
-    let aggregate = _.find(column, (g: any) => g.type === 'aggregate');
+    let aggregate = _.find(column, (g: any) => g.type === 'aggregate' || g.type === 'percentile');
     let special = _.find(column, (g: any) => g.type === 'window');
 
     if (aggregate) {
-      if (special) {
-        query = aggregate.params[0] + '(' + query + ' ORDER BY ' + this.target.timeColumn + ')';
-      } else {
-        query = aggregate.params[0] + '(' + query + ')';
+      switch (aggregate.type) {
+        case 'aggregate':
+          if (special) {
+            query = aggregate.params[0] + '(' + query + ' ORDER BY ' + this.target.timeColumn + ')';
+          } else {
+            query = aggregate.params[0] + '(' + query + ')';
+          }
+          break;
+        case 'percentile':
+          query = aggregate.params[0] + '(' + aggregate.params[1] + ') WITHIN GROUP (ORDER BY ' + query + ')';
+          break;
       }
     }
 

+ 40 - 10
public/app/plugins/datasource/postgres/query_ctrl.ts

@@ -112,6 +112,14 @@ export class PostgresQueryCtrl extends QueryCtrl {
           { text: 'Variance', value: 'variance' },
         ],
       },
+      {
+        text: 'Ordered-Set Aggregate Functions',
+        value: 'percentile',
+        submenu: [
+          { text: 'Percentile (continuous)', value: 'percentile_cont' },
+          { text: 'Percentile (discrete)', value: 'percentile_disc' },
+        ],
+      },
       {
         text: 'Window Functions',
         value: 'window',
@@ -121,9 +129,9 @@ export class PostgresQueryCtrl extends QueryCtrl {
           { text: 'Sum', value: 'sum' },
         ],
       },
-      { text: 'Alias', value: 'alias' },
-      { text: 'Column', value: 'column' },
     ];
+    this.selectMenu.push({ text: 'Alias', value: 'alias' });
+    this.selectMenu.push({ text: 'Column', value: 'column' });
   }
 
   toggleEditorMode() {
@@ -241,15 +249,17 @@ export class PostgresQueryCtrl extends QueryCtrl {
         });
         this.selectParts.push(parts);
         break;
+      case 'percentile':
+        partModel.params.push('0.95');
       case 'aggregate':
         // add group by if no group by yet
         if (this.target.group.length === 0) {
           this.addGroup('time', '1m');
         }
-      case 'window':
-        let index = _.findIndex(selectParts, (p: any) => p.def.type === item.value);
-        if (index !== -1) {
-          selectParts[index] = partModel;
+        let aggIndex = _.findIndex(selectParts, (p: any) => p.def.type === 'aggregate' || p.def.type === 'percentile');
+        if (aggIndex !== -1) {
+          // replace current aggregation
+          selectParts[aggIndex] = partModel;
         } else {
           selectParts.splice(1, 0, partModel);
         }
@@ -257,6 +267,26 @@ export class PostgresQueryCtrl extends QueryCtrl {
           addAlias = true;
         }
         break;
+      case 'window':
+        let windowIndex = _.findIndex(selectParts, (p: any) => p.def.type === 'window');
+        if (windowIndex !== -1) {
+          // replace current window function
+          selectParts[windowIndex] = partModel;
+        } else {
+          let aggIndex = _.findIndex(
+            selectParts,
+            (p: any) => p.def.type === 'aggregate' || p.def.type === 'percentile'
+          );
+          if (aggIndex !== -1) {
+            selectParts.splice(aggIndex + 1, 0, partModel);
+          } else {
+            selectParts.splice(1, 0, partModel);
+          }
+        }
+        if (!_.find(selectParts, (p: any) => p.def.type === 'alias')) {
+          addAlias = true;
+        }
+        break;
       case 'alias':
         addAlias = true;
         break;
@@ -322,7 +352,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     }
   }
 
-  onGroupPartEvent(part, index, evt) {
+  handleGroupPartEvent(part, index, evt) {
     switch (evt.name) {
       case 'get-param-options': {
         return this.datasource
@@ -379,7 +409,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
       // remove aggregations
       this.selectParts = _.map(this.selectParts, (s: any) => {
         return _.filter(s, (part: any) => {
-          if (part.def.type === 'aggregate') {
+          if (part.def.type === 'aggregate' || part.def.type === 'percentile') {
             return false;
           }
           return true;
@@ -436,7 +466,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
     return this.$q.when(options);
   }
 
-  whereAddAction(part, index) {
+  addWhereAction(part, index) {
     switch (this.whereAdd.type) {
       case 'macro': {
         this.whereParts.push(sqlPart.create({ type: 'macro', name: this.whereAdd.value, params: [] }));
@@ -468,7 +498,7 @@ export class PostgresQueryCtrl extends QueryCtrl {
       .catch(this.handleQueryError.bind(this));
   }
 
-  onGroupAction() {
+  addGroupAction() {
     switch (this.groupAdd.value) {
       default: {
         this.addGroup(this.groupAdd.type, this.groupAdd.value);

+ 26 - 1
public/app/plugins/datasource/postgres/sql_part.ts

@@ -45,10 +45,35 @@ register({
 register({
   type: 'aggregate',
   style: 'label',
-  params: [{ name: 'name', type: 'string', dynamicLookup: true }],
+  params: [
+    {
+      name: 'name',
+      type: 'string',
+      options: ['avg', 'count', 'min', 'max', 'sum', 'stddev', 'variance'],
+    },
+  ],
   defaultParams: ['avg'],
 });
 
+register({
+  type: 'percentile',
+  label: 'Aggregate:',
+  style: 'label',
+  params: [
+    {
+      name: 'name',
+      type: 'string',
+      options: ['percentile_cont', 'percentile_disc'],
+    },
+    {
+      name: 'fraction',
+      type: 'number',
+      options: ['0.5', '0.75', '0.9', '0.95', '0.99'],
+    },
+  ],
+  defaultParams: ['percentile_cont', '0.95'],
+});
+
 register({
   type: 'alias',
   style: 'label',