use of org.apache.druid.query.aggregation.post.FieldAccessPostAggregator in project druid by druid-io.
the class DoublesSketchApproxQuantileSqlAggregator method toDruidAggregation.
@Nullable
@Override
public Aggregation toDruidAggregation(final PlannerContext plannerContext, final RowSignature rowSignature, final VirtualColumnRegistry virtualColumnRegistry, final RexBuilder rexBuilder, final String name, final AggregateCall aggregateCall, final Project project, final List<Aggregation> existingAggregations, final boolean finalizeAggregations) {
final DruidExpression input = Aggregations.toDruidExpressionForNumericAggregator(plannerContext, rowSignature, Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(0)));
if (input == null) {
return null;
}
final AggregatorFactory aggregatorFactory;
final String histogramName = StringUtils.format("%s:agg", name);
final RexNode probabilityArg = Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(1));
if (!probabilityArg.isA(SqlKind.LITERAL)) {
// Probability must be a literal in order to plan.
return null;
}
final float probability = ((Number) RexLiteral.value(probabilityArg)).floatValue();
final int k;
if (aggregateCall.getArgList().size() >= 3) {
final RexNode resolutionArg = Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(2));
if (!resolutionArg.isA(SqlKind.LITERAL)) {
// Resolution must be a literal in order to plan.
return null;
}
k = ((Number) RexLiteral.value(resolutionArg)).intValue();
} else {
k = DoublesSketchAggregatorFactory.DEFAULT_K;
}
// Look for existing matching aggregatorFactory.
for (final Aggregation existing : existingAggregations) {
for (AggregatorFactory factory : existing.getAggregatorFactories()) {
if (factory instanceof DoublesSketchAggregatorFactory) {
final DoublesSketchAggregatorFactory theFactory = (DoublesSketchAggregatorFactory) factory;
// Check input for equivalence.
final boolean inputMatches;
final DruidExpression virtualInput = virtualColumnRegistry.findVirtualColumnExpressions(theFactory.requiredFields()).stream().findFirst().orElse(null);
if (virtualInput == null) {
inputMatches = input.isDirectColumnAccess() && input.getDirectColumn().equals(theFactory.getFieldName());
} else {
inputMatches = virtualInput.equals(input);
}
final boolean matches = inputMatches && theFactory.getK() == k;
if (matches) {
// Found existing one. Use this.
return Aggregation.create(ImmutableList.of(), new DoublesSketchToQuantilePostAggregator(name, new FieldAccessPostAggregator(factory.getName(), factory.getName()), probability));
}
}
}
}
// No existing match found. Create a new one.
if (input.isDirectColumnAccess()) {
aggregatorFactory = new DoublesSketchAggregatorFactory(histogramName, input.getDirectColumn(), k, getMaxStreamLengthFromQueryContext(plannerContext.getQueryContext()));
} else {
String virtualColumnName = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(input, ColumnType.FLOAT);
aggregatorFactory = new DoublesSketchAggregatorFactory(histogramName, virtualColumnName, k, getMaxStreamLengthFromQueryContext(plannerContext.getQueryContext()));
}
return Aggregation.create(ImmutableList.of(aggregatorFactory), new DoublesSketchToQuantilePostAggregator(name, new FieldAccessPostAggregator(histogramName, histogramName), probability));
}
use of org.apache.druid.query.aggregation.post.FieldAccessPostAggregator in project druid by druid-io.
the class DoublesSketchToHistogramPostAggregatorTest method emptySketch.
@Test
public void emptySketch() {
final TestDoubleColumnSelectorImpl selector = new TestDoubleColumnSelectorImpl(null);
final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
final Map<String, Object> fields = new HashMap<>();
fields.put("sketch", agg.get());
final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator("histogram", new FieldAccessPostAggregator("field", "sketch"), new double[] { 3.5 }, null);
final double[] histogram = (double[]) postAgg.compute(fields);
Assert.assertNotNull(histogram);
Assert.assertEquals(2, histogram.length);
Assert.assertTrue(Double.isNaN(histogram[0]));
Assert.assertTrue(Double.isNaN(histogram[1]));
}
use of org.apache.druid.query.aggregation.post.FieldAccessPostAggregator in project druid by druid-io.
the class DoublesSketchToHistogramPostAggregatorTest method testToString.
@Test
public void testToString() {
final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator("post", new FieldAccessPostAggregator("field1", "sketch"), new double[] { 0.25, 0.75 }, null);
Assert.assertEquals("DoublesSketchToHistogramPostAggregator{name='post', field=FieldAccessPostAggregator{name='field1', fieldName='sketch'}, splitPoints=[0.25, 0.75], numBins=null}", postAgg.toString());
}
use of org.apache.druid.query.aggregation.post.FieldAccessPostAggregator in project druid by druid-io.
the class DoublesSketchToHistogramPostAggregatorTest method testComparator.
@Test
public void testComparator() {
expectedException.expect(IAE.class);
expectedException.expectMessage("Comparing histograms is not supported");
final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator("post", new FieldAccessPostAggregator("field1", "sketch"), new double[] { 0.25, 0.75 }, null);
postAgg.getComparator();
}
use of org.apache.druid.query.aggregation.post.FieldAccessPostAggregator in project druid by druid-io.
the class DoublesSketchToHistogramPostAggregatorTest method testResultArraySignature.
@Test
public void testResultArraySignature() {
final TimeseriesQuery query = Druids.newTimeseriesQueryBuilder().dataSource("dummy").intervals("2000/3000").granularity(Granularities.HOUR).aggregators(new DoublesSketchAggregatorFactory("sketch", "col", 8)).postAggregators(new DoublesSketchToHistogramPostAggregator("a", new FieldAccessPostAggregator("field", "sketch"), new double[] { 3.5 }, null)).build();
Assert.assertEquals(RowSignature.builder().addTimeColumn().add("sketch", null).add("a", ColumnType.DOUBLE_ARRAY).build(), new TimeseriesQueryQueryToolChest().resultArraySignature(query));
}
Aggregations