use of io.druid.java.util.common.ISE in project druid by druid-io.
the class QueryMaker method executeSelect.
private Sequence<Object[]> executeSelect(final DruidQueryBuilder queryBuilder, final SelectQuery baseQuery) {
Preconditions.checkState(queryBuilder.getGrouping() == null, "grouping must be null");
final List<RelDataTypeField> fieldList = queryBuilder.getRowType().getFieldList();
final Integer limit = queryBuilder.getLimitSpec() != null ? queryBuilder.getLimitSpec().getLimit() : null;
// Select is paginated, we need to make multiple queries.
final Sequence<Sequence<Object[]>> sequenceOfSequences = Sequences.simple(new Iterable<Sequence<Object[]>>() {
@Override
public Iterator<Sequence<Object[]>> iterator() {
final AtomicBoolean morePages = new AtomicBoolean(true);
final AtomicReference<Map<String, Integer>> pagingIdentifiers = new AtomicReference<>();
final AtomicLong rowsRead = new AtomicLong();
// Each Sequence<Object[]> is one page.
return new Iterator<Sequence<Object[]>>() {
@Override
public boolean hasNext() {
return morePages.get();
}
@Override
public Sequence<Object[]> next() {
final SelectQuery queryWithPagination = baseQuery.withPagingSpec(new PagingSpec(pagingIdentifiers.get(), plannerContext.getPlannerConfig().getSelectThreshold(), true));
Hook.QUERY_PLAN.run(queryWithPagination);
morePages.set(false);
final AtomicBoolean gotResult = new AtomicBoolean();
return Sequences.concat(Sequences.map(queryWithPagination.run(walker, Maps.<String, Object>newHashMap()), new Function<Result<SelectResultValue>, Sequence<Object[]>>() {
@Override
public Sequence<Object[]> apply(final Result<SelectResultValue> result) {
if (!gotResult.compareAndSet(false, true)) {
throw new ISE("WTF?! Expected single result from Select query but got multiple!");
}
pagingIdentifiers.set(result.getValue().getPagingIdentifiers());
final List<Object[]> retVals = new ArrayList<>();
for (EventHolder holder : result.getValue().getEvents()) {
morePages.set(true);
final Map<String, Object> map = holder.getEvent();
final Object[] retVal = new Object[fieldList.size()];
for (RelDataTypeField field : fieldList) {
final String outputName = queryBuilder.getRowOrder().get(field.getIndex());
if (outputName.equals(Column.TIME_COLUMN_NAME)) {
retVal[field.getIndex()] = coerce(holder.getTimestamp().getMillis(), field.getType().getSqlTypeName());
} else {
retVal[field.getIndex()] = coerce(map.get(outputName), field.getType().getSqlTypeName());
}
}
if (limit == null || rowsRead.incrementAndGet() <= limit) {
retVals.add(retVal);
} else {
morePages.set(false);
return Sequences.simple(retVals);
}
}
return Sequences.simple(retVals);
}
}));
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
});
return Sequences.concat(sequenceOfSequences);
}
use of io.druid.java.util.common.ISE in project druid by druid-io.
the class GroupByRules method toLimitSpec.
public static DefaultLimitSpec toLimitSpec(final List<String> rowOrder, final Sort sort) {
final Integer limit = sort.fetch != null ? RexLiteral.intValue(sort.fetch) : null;
final List<OrderByColumnSpec> orderBys = Lists.newArrayListWithCapacity(sort.getChildExps().size());
if (sort.offset != null) {
// LimitSpecs don't accept offsets.
return null;
}
// Extract orderBy column specs.
for (int sortKey = 0; sortKey < sort.getChildExps().size(); sortKey++) {
final RexNode sortExpression = sort.getChildExps().get(sortKey);
final RelFieldCollation collation = sort.getCollation().getFieldCollations().get(sortKey);
final OrderByColumnSpec.Direction direction;
final StringComparator comparator;
if (collation.getDirection() == RelFieldCollation.Direction.ASCENDING) {
direction = OrderByColumnSpec.Direction.ASCENDING;
} else if (collation.getDirection() == RelFieldCollation.Direction.DESCENDING) {
direction = OrderByColumnSpec.Direction.DESCENDING;
} else {
throw new ISE("WTF?! Don't know what to do with direction[%s]", collation.getDirection());
}
final SqlTypeName sortExpressionType = sortExpression.getType().getSqlTypeName();
if (SqlTypeName.NUMERIC_TYPES.contains(sortExpressionType) || SqlTypeName.TIMESTAMP == sortExpressionType || SqlTypeName.DATE == sortExpressionType) {
comparator = StringComparators.NUMERIC;
} else {
comparator = StringComparators.LEXICOGRAPHIC;
}
if (sortExpression.isA(SqlKind.INPUT_REF)) {
final RexInputRef ref = (RexInputRef) sortExpression;
final String fieldName = rowOrder.get(ref.getIndex());
orderBys.add(new OrderByColumnSpec(fieldName, direction, comparator));
} else {
// We don't support sorting by anything other than refs which actually appear in the query result.
return null;
}
}
return new DefaultLimitSpec(orderBys, limit);
}
use of io.druid.java.util.common.ISE in project druid by druid-io.
the class DruidQueryBuilder method toSelectQuery.
/**
* Return this query as a Select query, or null if this query is not compatible with Select.
*
* @param dataSource data source to query
* @param sourceRowSignature row signature of the dataSource
* @param context query context
*
* @return query or null
*/
public SelectQuery toSelectQuery(final DataSource dataSource, final RowSignature sourceRowSignature, final Map<String, Object> context) {
if (grouping != null) {
return null;
}
final Filtration filtration = Filtration.create(filter).optimize(sourceRowSignature);
final boolean descending;
if (limitSpec != null) {
// Safe to assume limitSpec has zero or one entry; DruidSelectSortRule wouldn't push in anything else.
if (limitSpec.getColumns().size() > 0) {
final OrderByColumnSpec orderBy = Iterables.getOnlyElement(limitSpec.getColumns());
if (!orderBy.getDimension().equals(Column.TIME_COLUMN_NAME)) {
throw new ISE("WTF?! Got select with non-time orderBy[%s]", orderBy);
}
descending = orderBy.getDirection() == OrderByColumnSpec.Direction.DESCENDING;
} else {
descending = false;
}
} else {
descending = false;
}
return new SelectQuery(dataSource, filtration.getQuerySegmentSpec(), descending, filtration.getDimFilter(), Granularities.ALL, selectProjection != null ? selectProjection.getDimensions() : ImmutableList.<DimensionSpec>of(), selectProjection != null ? selectProjection.getMetrics() : ImmutableList.<String>of(), null, new PagingSpec(null, 0), /* dummy -- will be replaced */
context);
}
use of io.druid.java.util.common.ISE in project druid by druid-io.
the class Aggregation method filter.
public Aggregation filter(final DimFilter filter) {
if (filter == null) {
return this;
}
if (postAggregator != null) {
// Verify that this Aggregation contains all inputs. If not, this "filter" call won't work right.
final Set<String> dependentFields = postAggregator.getDependentFields();
final Set<String> aggregatorNames = Sets.newHashSet();
for (AggregatorFactory aggregatorFactory : aggregatorFactories) {
aggregatorNames.add(aggregatorFactory.getName());
}
for (String field : dependentFields) {
if (!aggregatorNames.contains(field)) {
throw new ISE("Cannot filter an Aggregation that does not contain its inputs: %s", this);
}
}
}
final List<AggregatorFactory> newAggregators = Lists.newArrayList();
for (AggregatorFactory agg : aggregatorFactories) {
newAggregators.add(new FilteredAggregatorFactory(agg, filter));
}
return new Aggregation(newAggregators, postAggregator, finalizingPostAggregatorFactory);
}
use of io.druid.java.util.common.ISE in project druid by druid-io.
the class ConvertSelectorsToIns method process.
@Override
public DimFilter process(DimFilter filter) {
if (filter instanceof OrDimFilter) {
// Copy children list
final List<DimFilter> children = Lists.newArrayList(((OrDimFilter) filter).getFields());
// Group filters by dimension and extractionFn.
final Map<BoundRefKey, List<SelectorDimFilter>> selectors = Maps.newHashMap();
for (DimFilter child : children) {
if (child instanceof SelectorDimFilter) {
final SelectorDimFilter selector = (SelectorDimFilter) child;
final BoundRefKey boundRefKey = BoundRefKey.from(selector, sourceRowSignature.naturalStringComparator(RowExtraction.of(selector.getDimension(), selector.getExtractionFn())));
List<SelectorDimFilter> filterList = selectors.get(boundRefKey);
if (filterList == null) {
filterList = Lists.newArrayList();
selectors.put(boundRefKey, filterList);
}
filterList.add(selector);
}
}
// Emit IN filters for each group of size > 1.
for (Map.Entry<BoundRefKey, List<SelectorDimFilter>> entry : selectors.entrySet()) {
final List<SelectorDimFilter> filterList = entry.getValue();
if (filterList.size() > 1) {
// We found a simplification. Remove the old filters and add new ones.
final List<String> values = Lists.newArrayList();
for (final SelectorDimFilter selector : filterList) {
values.add(selector.getValue());
if (!children.remove(selector)) {
throw new ISE("WTF?! Tried to remove selector but couldn't?");
}
}
children.add(new InDimFilter(entry.getKey().getDimension(), values, entry.getKey().getExtractionFn()));
}
}
if (!children.equals(((OrDimFilter) filter).getFields())) {
return children.size() == 1 ? children.get(0) : new OrDimFilter(children);
} else {
return filter;
}
} else {
return filter;
}
}
Aggregations