@Override public Object[] apply(final Result<TimeseriesResultValue> result) { final Map<String, Object> row = result.getValue().getBaseObject(); final Object[] retVal = new Object[fieldList.size()]; for (final RelDataTypeField field : fieldList) { final String outputName = druidQuery.getOutputRowSignature().getRowOrder().get(field.getIndex()); if (outputName.equals(timeOutputName)) { retVal[field.getIndex()] = coerce(result.getTimestamp(), field.getType().getSqlTypeName()); } else { retVal[field.getIndex()] = coerce(row.get(outputName), field.getType().getSqlTypeName()); } } return retVal; } }
private Function<Result<TimeseriesResultValue>, Result<TimeseriesResultValue>> makeComputeManipulatorFn( final TimeseriesQuery query, final MetricManipulationFn fn, final boolean calculatePostAggs ) { return result -> { final TimeseriesResultValue holder = result.getValue(); final Map<String, Object> values = new HashMap<>(holder.getBaseObject()); if (calculatePostAggs && !query.getPostAggregatorSpecs().isEmpty()) { // put non finalized aggregators for calculating dependent post Aggregators for (AggregatorFactory agg : query.getAggregatorSpecs()) { values.put(agg.getName(), holder.getMetric(agg.getName())); } for (PostAggregator postAgg : query.getPostAggregatorSpecs()) { values.put(postAgg.getName(), postAgg.compute(values)); } } for (AggregatorFactory agg : query.getAggregatorSpecs()) { values.put(agg.getName(), fn.manipulate(agg, holder.getMetric(agg.getName()))); } return new Result<>( result.getTimestamp(), new TimeseriesResultValue(values) ); }; } }
private static void assertTimeseriesResultValue(String msg, Result expected, Result actual) { // Custom equals check to get fuzzy comparison of numerics, useful because different groupBy strategies don't // always generate exactly the same results (different merge ordering / float vs double) Assert.assertEquals(StringUtils.format("%s: timestamp", msg), expected.getTimestamp(), actual.getTimestamp()); TimeseriesResultValue expectedVal = (TimeseriesResultValue) expected.getValue(); TimeseriesResultValue actualVal = (TimeseriesResultValue) actual.getValue(); final Map<String, Object> expectedMap = (Map<String, Object>) expectedVal.getBaseObject(); final Map<String, Object> actualMap = (Map<String, Object>) actualVal.getBaseObject(); assertRow(msg, new MapBasedRow(expected.getTimestamp(), expectedMap), new MapBasedRow(actual.getTimestamp(), actualMap)); }
@Test public void testTimeseriesNoAggregators() { Granularity gran = Granularities.DAY; TimeseriesQuery query = Druids.newTimeseriesQueryBuilder() .dataSource(QueryRunnerTestHelper.dataSource) .granularity(gran) .intervals(QueryRunnerTestHelper.fullOnIntervalSpec) .descending(descending) .build(); Iterable<Result<TimeseriesResultValue>> results = runner.run(QueryPlus.wrap(query), CONTEXT).toList(); final DateTime expectedLast = descending ? QueryRunnerTestHelper.earliest : QueryRunnerTestHelper.last; Result lastResult = null; for (Result<TimeseriesResultValue> result : results) { DateTime current = result.getTimestamp(); Assert.assertFalse( StringUtils.format("Timestamp[%s] > expectedLast[%s]", current, expectedLast), descending ? current.isBefore(expectedLast) : current.isAfter(expectedLast) ); Assert.assertEquals(ImmutableMap.of(), result.getValue().getBaseObject()); lastResult = result; } Assert.assertEquals(lastResult.toString(), expectedLast, lastResult.getTimestamp()); }
@Override public Object[] apply(final Result<TimeseriesResultValue> result) { final Map<String, Object> row = result.getValue().getBaseObject(); final Object[] retVal = new Object[fieldList.size()]; for (final RelDataTypeField field : fieldList) { final String outputName = druidQuery.getOutputRowSignature().getRowOrder().get(field.getIndex()); if (outputName.equals(timeOutputName)) { retVal[field.getIndex()] = coerce(result.getTimestamp(), field.getType().getSqlTypeName()); } else { retVal[field.getIndex()] = coerce(row.get(outputName), field.getType().getSqlTypeName()); } } return retVal; } }
private Function<Result<TimeseriesResultValue>, Result<TimeseriesResultValue>> makeComputeManipulatorFn( final TimeseriesQuery query, final MetricManipulationFn fn, final boolean calculatePostAggs ) { return result -> { final TimeseriesResultValue holder = result.getValue(); final Map<String, Object> values = Maps.newHashMap(holder.getBaseObject()); if (calculatePostAggs && !query.getPostAggregatorSpecs().isEmpty()) { // put non finalized aggregators for calculating dependent post Aggregators for (AggregatorFactory agg : query.getAggregatorSpecs()) { values.put(agg.getName(), holder.getMetric(agg.getName())); } for (PostAggregator postAgg : query.getPostAggregatorSpecs()) { values.put(postAgg.getName(), postAgg.compute(values)); } } for (AggregatorFactory agg : query.getAggregatorSpecs()) { values.put(agg.getName(), fn.manipulate(agg, holder.getMetric(agg.getName()))); } return new Result<>( result.getTimestamp(), new TimeseriesResultValue(values) ); }; } }