Support InfluxDB count distinct aggregation (#11658)

influxdb: support count distinct aggregation
This commit is contained in:
Kim Christensen 2018-05-30 09:22:16 +02:00 committed by Marcus Efraimsson
parent f32e3a2960
commit 48fc5edda1
3 changed files with 175 additions and 0 deletions

View File

@ -76,5 +76,13 @@ func TestInfluxdbQueryPart(t *testing.T) {
res := part.Render(query, queryContext, "mean(value)")
So(res, ShouldEqual, `mean(value) AS "test"`)
})
Convey("render count distinct", func() {
part, err := NewQueryPart("count", []string{})
So(err, ShouldBeNil)
res := part.Render(query, queryContext, "distinct(value)")
So(res, ShouldEqual, `count(distinct(value))`)
})
})
}

View File

@ -44,6 +44,28 @@ function replaceAggregationAddStrategy(selectParts, partModel) {
for (var i = 0; i < selectParts.length; i++) {
var part = selectParts[i];
if (part.def.category === categories.Aggregations) {
if (part.def.type === partModel.def.type) {
return;
}
// count distinct is allowed
if (part.def.type === 'count' && partModel.def.type === 'distinct') {
break;
}
// remove next aggregation if distinct was replaced
if (part.def.type === 'distinct') {
var morePartsAvailable = selectParts.length >= i + 2;
if (partModel.def.type !== 'count' && morePartsAvailable) {
var nextPart = selectParts[i + 1];
if (nextPart.def.category === categories.Aggregations) {
selectParts.splice(i + 1, 1);
}
} else if (partModel.def.type === 'count') {
if (!morePartsAvailable || selectParts[i + 1].def.type !== 'count') {
selectParts.splice(i + 1, 0, partModel);
}
return;
}
}
selectParts[i] = partModel;
return;
}
@ -434,4 +456,5 @@ export default {
getCategories: function() {
return categories;
},
replaceAggregationAdd: replaceAggregationAddStrategy,
};

View File

@ -40,5 +40,149 @@ describe('InfluxQueryPart', () => {
expect(part.text).toBe('alias(test)');
expect(part.render('mean(value)')).toBe('mean(value) AS "test"');
});
it('should nest distinct when count is selected', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('distinct()');
expect(selectParts[2].text).toBe('count()');
});
it('should convert to count distinct when distinct is selected and count added', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('distinct()');
expect(selectParts[2].text).toBe('count()');
});
it('should replace count distinct if an aggregation is selected', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
}),
queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'mean',
category: queryPart.getCategories().Selectors,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('mean()');
expect(selectParts).toHaveLength(2);
});
it('should not allowed nested counts when count distinct is selected', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
}),
queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('distinct()');
expect(selectParts[2].text).toBe('count()');
expect(selectParts).toHaveLength(3);
});
it('should not remove count distinct when distinct is added', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
}),
queryPart.create({
type: 'count',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('distinct()');
expect(selectParts[2].text).toBe('count()');
expect(selectParts).toHaveLength(3);
});
it('should remove distinct when sum aggregation is selected', () => {
var selectParts = [
queryPart.create({
type: 'field',
category: queryPart.getCategories().Fields,
}),
queryPart.create({
type: 'distinct',
category: queryPart.getCategories().Aggregations,
}),
];
var partModel = queryPart.create({
type: 'sum',
category: queryPart.getCategories().Aggregations,
});
queryPart.replaceAggregationAdd(selectParts, partModel);
expect(selectParts[1].text).toBe('sum()');
});
});
});