sibling = sibling.nest(); self = self.nest(); Set<Aggregation> mergedAggregations = mergeAggregations(self.getAggregations(), sibling.getAggregations()); LinkedHashSet<PostAggregation> mergedPostAggregations = new LinkedHashSet<>(self.getPostAggregations()); mergedPostAggregations.addAll(sibling.getPostAggregations()); ZonelessTimeGrain mergedGrain = mergeTimeGrains(self.getTimeGrain(), sibling.getTimeGrain()); TemplateDruidQuery mergedNested = self.isNested() ? self.nestedQuery.merge(sibling.getInnerQuery().get()) : null; return new TemplateDruidQuery( mergedAggregations, mergedPostAggregations,
/** * Checks if the template druid query is nested. * * @return true if query is nested else false. */ public boolean isNested() { return (depth() > 1); }
/** * Create the inner query for an average. * * @param sourceMetric The metric being averaged over * @param innerDependentQuery The original query supporting the metric being averaged * * @return A template query representing the inner aggregation */ private TemplateDruidQuery buildInnerQuery(MetricField sourceMetric, TemplateDruidQuery innerDependentQuery) { Set<PostAggregation> newInnerPostAggregations = (sourceMetric instanceof PostAggregation) ? ImmutableSet.of((PostAggregation) sourceMetric) : Collections.emptySet(); // Build the inner query with the new aggregations and with the count return innerDependentQuery.withAggregations(innerDependentQuery.getAggregations()) .withPostAggregations(newInnerPostAggregations) .merge(buildTimeGrainCounterQuery()); }
@Override public TemplateDruidQuery updateOuterQuery( TemplateDruidQuery outerQuery, Map<String, String> oldFieldNameToNewFieldNameMap ) { Map<String, Aggregation> oldNameToNewAggregationMapping = new HashMap<>(); Set<Aggregation> updatedOuterAggs = updateQueryAggs( outerQuery.getAggregations(), oldFieldNameToNewFieldNameMap, oldNameToNewAggregationMapping ); //Update the FieldAccessors from the outer query post aggs to access the correct aggs. Set<PostAggregation> updateOuterPostAggs = new HashSet<>(); for (PostAggregation postAggregation: outerQuery.getPostAggregations()) { updateOuterPostAggs.add(replacePostAggWithPostAggFromMap(postAggregation, oldNameToNewAggregationMapping)); } //create new TDQ using updated aggs, updatedPostAggs, updatedInnerQuery and timegrain of outerQuery return new TemplateDruidQuery( updatedOuterAggs, updateOuterPostAggs, outerQuery.getInnerQuery().orElse(null), outerQuery.getTimeGrain() ); }
/** * Makes a copy of the template query, changing nested query. * <p> * Everything is a shallow copy. * * @param newNestedQuery The nestedQuery to replace in the copy * * @return copy of the query */ public TemplateDruidQuery withInnerQuery(TemplateDruidQuery newNestedQuery) { return new TemplateDruidQuery(aggregations, postAggregations, newNestedQuery, timeGrain); }
Granularity mergedGranularity = template.getTimeGrain() != null ? template.getTimeGrain().buildZonedTimeGrain(timeZone) : granularity; if (!template.isNested()) { LOG.trace("Building a single pass druid groupBy query"); dataSource = buildTableDataSource(table); template.getInnerQuery().get(), table, mergedGranularity, mergedFilter, having, template.getAggregations(), template.getPostAggregations(), intervals, druidOrderBy
if (templateDruidQuery.isNested()) { templateDruidQuery.getInnerQuery().get(), metricFilterObject, dimensionDictionary, newInnerQuery = newInnerQuery.withPostAggregations( updateNestedQueryPostAggs( newInnerQuery.getPostAggregations(), innerPostAggToOuterAggMap, filterSuffix templateDruidQuery.withInnerQuery(newInnerQuery), innerPostAggToOuterAggMap );
if (template.getTimeGrain() != null) { granularity = template.getTimeGrain().buildZonedTimeGrain(timeZone); granularity, filter, template.getAggregations(), template.getPostAggregations(), intervals );
if (isNested()) { innerQuery = new TemplateDruidQuery(innerAggregations, Collections.emptySet(), nestedQuery, null); } else { innerQuery = new TemplateDruidQuery( innerAggregations, Collections.emptySet(), return new TemplateDruidQuery(outerAggregations, postAggregations, innerQuery, timeGrain);
@Override protected LogicalMetric makeInner(LogicalMetricInfo logicalMetricInfo, List<String> dependentMetrics) { LogicalMetric sourceMetric = metricDictionary.get(dependentMetrics.get(0)); Aggregation sourceAggregation = assertDependentIsAggregationMetric(sourceMetric); FilteredAggregation filteredAggregation = new FilteredAggregation( logicalMetricInfo.getName(), sourceAggregation, filter ); return new LogicalMetric( new TemplateDruidQuery( ImmutableSet.of(filteredAggregation), Collections.emptySet(), sourceMetric.getTemplateDruidQuery().getInnerQuery().orElse(null) ), sourceMetric.getCalculation(), logicalMetricInfo ); }
/** * Template Query constructor for a nested template query with a bound time grain. * * @param aggregations aggregations for this query template * @param postAggregations post aggregations for this query template * @param nestedQuery A query which this query uses as a data source * @param timeGrain The time grain constraint on the query if any */ public TemplateDruidQuery( Collection<Aggregation> aggregations, Collection<PostAggregation> postAggregations, TemplateDruidQuery nestedQuery, ZonelessTimeGrain timeGrain ) { // Convert the sets to LinkedHashSet to preserve order, and then make them unmodifiable this.aggregations = Collections.unmodifiableSet(new LinkedHashSet<>(aggregations)); this.postAggregations = Collections.unmodifiableSet(new LinkedHashSet<>(postAggregations)); this.nestedQuery = nestedQuery; this.timeGrain = timeGrain; // Check for duplicate field names Set<String> nameCollisions = getNameCollisions(aggregations, postAggregations); if (!nameCollisions.isEmpty()) { String message = "Duplicate name in aggregation & post aggregations: " + nameCollisions; LOG.error(message); throw new IllegalArgumentException(message); } depth = calculateDepth(this); }
/** * Get the a granularity which must be satisfied by any answering table granularity for this request. * <p> * If a query has a time grain constraint, it will be returned as a granularity with the request time zone * applied. If the query has no constraint, the request grain will be returned as a granularity. * * @param apiRequest DataApiRequest from the user which may specify a coarsest satisfying grain * @param query Query which may apply a coarsest satisfying grain * * @return The coarsest valid table grain to satisfy the query */ public Granularity resolveAcceptingGrain(DataApiRequest apiRequest, TemplateDruidQuery query) { // Gather any specified time grains Granularity requestGranularity = apiRequest.getGranularity(); ZonelessTimeGrain queryGrain = query.getInnermostQuery().getTimeGrain(); // The query makes no restrictions, so use the apiRequest only if (queryGrain == null) { return requestGranularity; } if (requestGranularity.satisfiedBy(queryGrain)) { return queryGrain.buildZonedTimeGrain(apiRequest.getTimeZone()); } LOG.error(QUERY_GRAIN_NOT_SATISFIED.format(queryGrain, requestGranularity)); throw new IllegalArgumentException(QUERY_GRAIN_NOT_SATISFIED.format(queryGrain, requestGranularity)); }
/** * Calculate the depth of the candidate TemplateDruidQuery. * * @param candidate TemplateDruidQuery to calculate the depth of * * @return The depth of the candidate query */ private int calculateDepth(TemplateDruidQuery candidate) { int theDepth = 1; Optional<TemplateDruidQuery> iterator = candidate.getInnerQuery(); while (iterator.isPresent()) { theDepth++; iterator = iterator.get().getInnerQuery(); } return theDepth; }
/** * Check if outer TimeGrain is compatible with inner TimeGrain. * * @return false if outer TimeGrain cannot be composed by the inner time grain */ public boolean isTimeGrainValid() { if (nestedQuery != null) { TimeGrain nestedTimeGrain = nestedQuery.getTimeGrain(); // Nested time grain must be smaller or equal to this time grain return timeGrain == null || nestedTimeGrain == null || timeGrain.satisfiedBy(nestedTimeGrain); } return true; }
public MetricField getMetricField() { return getTemplateDruidQuery().getMetricField(getName()); }
) throws FilterBuilderException { Set<PostAggregation> postAggregations = query.getPostAggregations(); Set<PostAggregation> updatedPostAggs = new HashSet<>(); Set<Aggregation> updatedAggs = new HashSet<>(); for (Aggregation aggregation : query.getAggregations()) { return new TemplateDruidQuery( updatedAggs, updatedPostAggs, query.getInnerQuery().orElse(null), query.getTimeGrain() );
/** * Makes a copy of the template query and any sub query(s), changing post-aggregations. * <p> * Everything is a shallow copy. * * @param newPostAggregations The PostAggregations to replace with in the copy * * @return copy of the query */ public TemplateDruidQuery withPostAggregations(Collection<PostAggregation> newPostAggregations) { return new TemplateDruidQuery(aggregations, newPostAggregations, nestedQuery, timeGrain); }
Granularity mergeGrain = (template.getTimeGrain() != null) ? template.getTimeGrain().buildZonedTimeGrain(timeZone) : granularity; groupByDimension.iterator().next(), filter, template.getAggregations(), template.getPostAggregations(), intervals, topN,
/** * Makes a copy of the template query and any sub query(s), changing time grain on the outermost level only. * <p> * Everything is a shallow copy. * * @param newTimeGrain The TimeGrain to replace with in the copy * * @return copy of the query */ public TemplateDruidQuery withGranularity(ZonelessTimeGrain newTimeGrain) { return new TemplateDruidQuery(aggregations, postAggregations, nestedQuery, newTimeGrain); }
/** * Makes a copy of the template query and any sub query(s), changing aggregations. * <p> * Everything is a shallow copy. * * @param newAggregations The Aggregations to replace in the copy * * @return copy of the query */ @Override public TemplateDruidQuery withAggregations(Collection<Aggregation> newAggregations) { return new TemplateDruidQuery(newAggregations, postAggregations, nestedQuery, timeGrain); }