use of io.crate.analyze.OrderBy in project crate by crate.
the class DocInputFactory method extractImplementations.
public InputFactory.Context<? extends LuceneCollectorExpression<?>> extractImplementations(RoutedCollectPhase phase) {
OrderBy orderBy = phase.orderBy();
ReferenceResolver<? extends LuceneCollectorExpression<?>> refResolver;
if (orderBy == null) {
refResolver = referenceResolver;
} else {
refResolver = ref -> {
if (orderBy.orderBySymbols().contains(ref)) {
return new OrderByCollectorExpression(ref, orderBy);
}
return referenceResolver.getImplementation(ref);
};
}
InputFactory.Context<? extends LuceneCollectorExpression<?>> ctx = inputFactory.ctxForRefs(refResolver);
ctx.add(phase.toCollect());
return ctx;
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class TableFunctionCollectSource method getCollector.
@Override
public CrateCollector getCollector(CollectPhase collectPhase, BatchConsumer consumer, JobCollectContext jobCollectContext) {
TableFunctionCollectPhase phase = (TableFunctionCollectPhase) collectPhase;
WhereClause whereClause = phase.whereClause();
if (whereClause.noMatch()) {
return RowsCollector.empty(consumer);
}
TableFunctionImplementation functionImplementation = phase.relation().functionImplementation();
TableInfo tableInfo = functionImplementation.createTableInfo(clusterService);
//noinspection unchecked Only literals can be passed to table functions. Anything else is invalid SQL
List<Input<?>> inputs = (List<Input<?>>) (List) phase.relation().function().arguments();
List<Reference> columns = new ArrayList<>(tableInfo.columns());
List<Input<?>> topLevelInputs = new ArrayList<>(phase.toCollect().size());
InputFactory.Context<InputCollectExpression> ctx = inputFactory.ctxForRefs(i -> new InputCollectExpression(columns.indexOf(i)));
for (Symbol symbol : phase.toCollect()) {
topLevelInputs.add(ctx.add(symbol));
}
Iterable<Row> rows = Iterables.transform(functionImplementation.execute(inputs), new ValueAndInputRow<>(topLevelInputs, ctx.expressions()));
if (whereClause.hasQuery()) {
Input<Boolean> condition = (Input<Boolean>) ctx.add(whereClause.query());
rows = Iterables.filter(rows, InputCondition.asPredicate(condition));
}
OrderBy orderBy = phase.orderBy();
if (orderBy != null) {
rows = RowsTransformer.sortRows(Iterables.transform(rows, Row::materialize), phase);
}
return RowsCollector.forRows(rows, phase.toCollect().size(), consumer);
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class QueriedDocTableFetchPushDown method pushDown.
@Nullable
QueriedDocTable pushDown() {
if (querySpec.groupBy().isPresent() || querySpec.having().isPresent() || querySpec.hasAggregates()) {
return null;
}
Optional<OrderBy> orderBy = querySpec.orderBy();
FetchRequiredVisitor.Context context;
if (orderBy.isPresent()) {
context = new FetchRequiredVisitor.Context(new LinkedHashSet<>(orderBy.get().orderBySymbols()));
} else {
context = new FetchRequiredVisitor.Context();
}
boolean fetchRequired = FetchRequiredVisitor.INSTANCE.process(querySpec.outputs(), context);
if (!fetchRequired)
return null;
// build the subquery
QuerySpec sub = new QuerySpec();
Reference docIdReference = DocSysColumns.forTable(tableRelation.tableInfo().ident(), DocSysColumns.FETCHID);
List<Symbol> outputs = new ArrayList<>();
if (orderBy.isPresent()) {
sub.orderBy(orderBy.get());
outputs.add(docIdReference);
outputs.addAll(context.querySymbols());
} else {
outputs.add(docIdReference);
}
for (Symbol symbol : querySpec.outputs()) {
if (Symbols.containsColumn(symbol, DocSysColumns.SCORE) && !outputs.contains(symbol)) {
outputs.add(symbol);
}
}
sub.outputs(outputs);
QueriedDocTable subRelation = new QueriedDocTable(tableRelation, sub);
HashMap<Symbol, InputColumn> symbolMap = new HashMap<>(sub.outputs().size());
int index = 0;
for (Symbol symbol : sub.outputs()) {
symbolMap.put(symbol, new InputColumn(index++, symbol.valueType()));
}
// push down the where clause
sub.where(querySpec.where());
querySpec.where(null);
ToFetchReferenceVisitor toFetchReferenceVisitor = new ToFetchReferenceVisitor();
toFetchReferenceVisitor.processInplace(querySpec.outputs(), symbolMap);
if (orderBy.isPresent()) {
// replace order by symbols with input columns, we need to copy the order by since it was pushed down to the
// subquery before
List<Symbol> newOrderBySymbols = MappingSymbolVisitor.copying().process(orderBy.get().orderBySymbols(), symbolMap);
querySpec.orderBy(new OrderBy(newOrderBySymbols, orderBy.get().reverseFlags(), orderBy.get().nullsFirst()));
}
sub.limit(querySpec.limit());
sub.offset(querySpec.offset());
return subRelation;
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class RoutedCollectPhase method normalize.
/**
* normalizes the symbols of this node with the given normalizer
*
* @return a normalized node, if no changes occurred returns this
*/
public RoutedCollectPhase normalize(EvaluatingNormalizer normalizer, TransactionContext transactionContext) {
assert whereClause() != null : "whereClause must not be null";
RoutedCollectPhase result = this;
List<Symbol> newToCollect = normalizer.normalize(toCollect(), transactionContext);
boolean changed = newToCollect != toCollect();
WhereClause newWhereClause = whereClause().normalize(normalizer, transactionContext);
OrderBy orderBy = this.orderBy;
if (orderBy != null) {
List<Symbol> orderBySymbols = orderBy.orderBySymbols();
List<Symbol> normalizedOrderBy = normalizer.normalize(orderBySymbols, transactionContext);
changed = changed || orderBySymbols != normalizedOrderBy;
orderBy = new OrderBy(normalizedOrderBy, this.orderBy.reverseFlags(), this.orderBy.nullsFirst());
}
changed = changed || newWhereClause != whereClause();
if (changed) {
result = new RoutedCollectPhase(jobId(), phaseId(), name(), routing, maxRowGranularity, newToCollect, projections, newWhereClause, distributionInfo);
result.orderBy(orderBy);
}
return result;
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class ShardCollectSource method getCollector.
@Override
public CrateCollector getCollector(CollectPhase phase, BatchConsumer lastConsumer, JobCollectContext jobCollectContext) {
RoutedCollectPhase collectPhase = (RoutedCollectPhase) phase;
RoutedCollectPhase normalizedPhase = collectPhase.normalize(nodeNormalizer, null);
String localNodeId = clusterService.localNode().getId();
BatchConsumer firstConsumer = ProjectingBatchConsumer.create(lastConsumer, Projections.nodeProjections(normalizedPhase.projections()), collectPhase.jobId(), jobCollectContext.queryPhaseRamAccountingContext(), sharedProjectorFactory);
if (normalizedPhase.maxRowGranularity() == RowGranularity.SHARD) {
// The getShardsCollector method always only uses a single RowReceiver and not one per shard)
return getShardsCollector(collectPhase, normalizedPhase, localNodeId, firstConsumer);
}
OrderBy orderBy = normalizedPhase.orderBy();
if (normalizedPhase.maxRowGranularity() == RowGranularity.DOC && orderBy != null) {
return createMultiShardScoreDocCollector(normalizedPhase, firstConsumer, jobCollectContext, localNodeId);
}
// actual shards might be less if table is partitioned and a partition has been deleted meanwhile
final int maxNumShards = normalizedPhase.routing().numShards(localNodeId);
boolean hasShardProjections = Projections.hasAnyShardProjections(normalizedPhase.projections());
Map<String, Map<String, List<Integer>>> locations = normalizedPhase.routing().locations();
final List<CrateCollector.Builder> builders = new ArrayList<>(maxNumShards);
Map<String, List<Integer>> indexShards = locations.get(localNodeId);
if (indexShards != null) {
builders.addAll(getDocCollectors(jobCollectContext, normalizedPhase, lastConsumer.requiresScroll(), indexShards));
}
switch(builders.size()) {
case 0:
return RowsCollector.empty(firstConsumer);
case 1:
CrateCollector.Builder collectorBuilder = builders.iterator().next();
return collectorBuilder.build(collectorBuilder.applyProjections(firstConsumer));
default:
if (hasShardProjections) {
// in order to process shard-based projections concurrently
return new CompositeCollector(builders, firstConsumer, iterators -> new AsyncCompositeBatchIterator(executor, iterators));
} else {
return new CompositeCollector(builders, firstConsumer, CompositeBatchIterator::new);
}
}
}
Aggregations