瀏覽代碼

refactor column function handling

Sven Klemm 7 年之前
父節點
當前提交
5327580939

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

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

+ 11 - 4
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;
       }
     }
 

+ 27 - 4
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;

+ 11 - 6
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"'
     );
   });
 

+ 2 - 2
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'],