refactor function handling in query builder

This commit is contained in:
Sven Klemm
2018-07-29 13:30:21 +02:00
parent 5327580939
commit 412bb6acab
4 changed files with 81 additions and 19 deletions

View File

@ -66,7 +66,7 @@
</div> </div>
<div class="gf-form"> <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>
<div class="gf-form gf-form--grow"> <div class="gf-form gf-form--grow">
@ -83,12 +83,12 @@
<sql-part-editor ng-repeat="part in ctrl.groupParts" <sql-part-editor ng-repeat="part in ctrl.groupParts"
part="part" class="gf-form-label sql-part" 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> </sql-part-editor>
</div> </div>
<div class="gf-form"> <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>
<div class="gf-form gf-form--grow"> <div class="gf-form gf-form--grow">

View File

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

View File

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

View File

@ -45,10 +45,35 @@ register({
register({ register({
type: 'aggregate', type: 'aggregate',
style: 'label', style: 'label',
params: [{ name: 'name', type: 'string', dynamicLookup: true }], params: [
{
name: 'name',
type: 'string',
options: ['avg', 'count', 'min', 'max', 'sum', 'stddev', 'variance'],
},
],
defaultParams: ['avg'], 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({ register({
type: 'alias', type: 'alias',
style: 'label', style: 'label',