public static StringComparator getComparatorForDimName(DefaultLimitSpec limitSpec, String dimName) { final OrderByColumnSpec orderBy = OrderByColumnSpec.getOrderByForDimName(limitSpec.getColumns(), dimName); if (orderBy == null) { return null; } return orderBy.getDimensionComparator(); }
@Override public Sequence<Row> apply(final Sequence<Row> input) { return new TopNSequence<>(input, ordering, limit); } }
public static OrderByColumnSpec asc(String dimension) { return new OrderByColumnSpec(dimension, Direction.ASCENDING, null); }
public GroupByQuery build() { final LimitSpec theLimitSpec; if (limitSpec == null) { if (orderByColumnSpecs.isEmpty() && limit == Integer.MAX_VALUE) { theLimitSpec = NoopLimitSpec.instance(); } else { theLimitSpec = new DefaultLimitSpec(orderByColumnSpecs, limit); } } else { theLimitSpec = limitSpec; } return new GroupByQuery( dataSource, querySegmentSpec, virtualColumns, dimFilter, granularity, dimensions, aggregatorSpecs, postAggregatorSpecs, havingSpec, theLimitSpec, subtotalsSpec, postProcessingFn, context ); } }
private boolean validateAndGetForceLimitPushDown() { final boolean forcePushDown = getContextBoolean(GroupByQueryConfig.CTX_KEY_FORCE_LIMIT_PUSH_DOWN, false); if (forcePushDown) { if (!(limitSpec instanceof DefaultLimitSpec)) { throw new IAE("When forcing limit push down, a limit spec must be provided."); } if (!((DefaultLimitSpec) limitSpec).isLimited()) { throw new IAE("When forcing limit push down, the provided limit spec must have a limit."); } if (havingSpec != null) { throw new IAE("Cannot force limit push down when a having spec is present."); } for (OrderByColumnSpec orderBySpec : ((DefaultLimitSpec) limitSpec).getColumns()) { if (OrderByColumnSpec.getPostAggIndexForOrderBy(orderBySpec, postAggregatorSpecs) > -1) { throw new UnsupportedOperationException("Limit push down when sorting by a post aggregator is not supported."); } } } return forcePushDown; }
/** * Check if a limitSpec has columns in the sorting order that are not part of the grouping fields represented * by `dimensions`. * * @param limitSpec LimitSpec, assumed to be non-null * @param dimensions Grouping fields for a groupBy query * @return True if limitSpec has sorting columns not contained in dimensions */ public static boolean sortingOrderHasNonGroupingFields(DefaultLimitSpec limitSpec, List<DimensionSpec> dimensions) { for (OrderByColumnSpec orderSpec : limitSpec.getColumns()) { int dimIndex = OrderByColumnSpec.getDimIndexForOrderBy(orderSpec, dimensions); if (dimIndex < 0) { return true; } } return false; }
public static int getAggIndexForOrderBy(OrderByColumnSpec orderSpec, List<AggregatorFactory> aggregatorFactories) { int i = 0; for (AggregatorFactory agg : aggregatorFactories) { if (orderSpec.getDimension().equals((agg.getName()))) { return i; } i++; } return -1; }
@JsonValue @Override public String toString() { return StringUtils.toLowerCase(this.name()); }
@Override public OrderByColumnSpec apply(@Nullable String input) { return desc(input); } }
@Override public OrderByColumnSpec apply(@Nullable String input) { return asc(input); } }
static LimitSpec nullToNoopLimitSpec(@Nullable LimitSpec limitSpec) { return (limitSpec == null) ? NoopLimitSpec.instance() : limitSpec; }
@Override public int hashCode() { int result = dimension.hashCode(); result = 31 * result + direction.hashCode(); result = 31 * result + dimensionComparator.hashCode(); return result; }
private Ordering<Row> dimensionOrdering(final String dimension, final StringComparator comparator) { return Ordering.from( Comparator.comparing((Row row) -> getDimensionValue(row, dimension), Comparator.nullsFirst(comparator)) ); }
public static OrderByColumnSpec desc(String dimension) { return new OrderByColumnSpec(dimension, Direction.DESCENDING, null); }
public static int getPostAggIndexForOrderBy(OrderByColumnSpec orderSpec, List<PostAggregator> postAggs) { int i = 0; for (PostAggregator postAgg : postAggs) { if (orderSpec.getDimension().equals((postAgg.getName()))) { return i; } i++; } return -1; }
public byte[] getCacheKey() { final byte[] dimensionBytes = StringUtils.toUtf8(dimension); final byte[] directionBytes = StringUtils.toUtf8(direction.name()); return ByteBuffer.allocate(dimensionBytes.length + directionBytes.length) .put(dimensionBytes) .put(directionBytes) .array(); } }
@JsonCreator public static OrderByColumnSpec fromString(String dimension) { return new OrderByColumnSpec(dimension, null, null); }
public static int getDimIndexForOrderBy(OrderByColumnSpec orderSpec, List<DimensionSpec> dimensions) { int i = 0; for (DimensionSpec dimSpec : dimensions) { if (orderSpec.getDimension().equals((dimSpec.getOutputName()))) { return i; } i++; } return -1; }
public Builder addOrderByColumn(String dimension, OrderByColumnSpec.Direction direction) { return addOrderByColumn(new OrderByColumnSpec(dimension, direction)); }