Search in sources :

Example 11 with OrderBy

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;
}
Also used : OrderBy(io.crate.analyze.OrderBy) InputFactory(io.crate.operation.InputFactory) OrderByCollectorExpression(io.crate.operation.reference.doc.lucene.OrderByCollectorExpression)

Example 12 with OrderBy

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);
}
Also used : OrderBy(io.crate.analyze.OrderBy) InputFactory(io.crate.operation.InputFactory) TableFunctionImplementation(io.crate.metadata.tablefunctions.TableFunctionImplementation) Reference(io.crate.metadata.Reference) Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause) ArrayList(java.util.ArrayList) Input(io.crate.data.Input) TableInfo(io.crate.metadata.table.TableInfo) ArrayList(java.util.ArrayList) List(java.util.List) Row(io.crate.data.Row) TableFunctionCollectPhase(io.crate.planner.node.dql.TableFunctionCollectPhase)

Example 13 with OrderBy

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;
}
Also used : OrderBy(io.crate.analyze.OrderBy) Reference(io.crate.metadata.Reference) QueriedDocTable(io.crate.analyze.relations.QueriedDocTable) QuerySpec(io.crate.analyze.QuerySpec) Nullable(javax.annotation.Nullable)

Example 14 with OrderBy

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;
}
Also used : OrderBy(io.crate.analyze.OrderBy) Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause)

Example 15 with OrderBy

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);
            }
    }
}
Also used : OrderBy(io.crate.analyze.OrderBy) CompositeCollector(io.crate.operation.collect.collectors.CompositeCollector) LuceneQueryBuilder(io.crate.lucene.LuceneQueryBuilder) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) RoutedCollectPhase(io.crate.planner.node.dql.RoutedCollectPhase) ProjectingBatchConsumer(io.crate.operation.projectors.ProjectingBatchConsumer)

Aggregations

OrderBy (io.crate.analyze.OrderBy)27 Test (org.junit.Test)14 QuerySpec (io.crate.analyze.QuerySpec)13 QueriedDocTable (io.crate.analyze.relations.QueriedDocTable)8 Symbol (io.crate.analyze.symbol.Symbol)8 CrateUnitTest (io.crate.test.integration.CrateUnitTest)5 InputFactory (io.crate.operation.InputFactory)4 WhereClause (io.crate.analyze.WhereClause)3 Row (io.crate.data.Row)3 Reference (io.crate.metadata.Reference)3 RoutedCollectPhase (io.crate.planner.node.dql.RoutedCollectPhase)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 ShardId (org.elasticsearch.index.shard.ShardId)3 Function (io.crate.analyze.symbol.Function)2 AbsFunction (io.crate.operation.scalar.arithmetic.AbsFunction)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 StandardAnalyzer (org.apache.lucene.analysis.standard.StandardAnalyzer)2 Document (org.apache.lucene.document.Document)2