Search in sources :

Example 1 with OrderBy

use of io.crate.analyze.OrderBy in project crate by crate.

the class RelationSplitter method processOrderBy.

private void processOrderBy() {
    if (!querySpec.orderBy().isPresent()) {
        return;
    }
    OrderBy orderBy = querySpec.orderBy().get();
    Set<AnalyzedRelation> relations = Collections.newSetFromMap(new IdentityHashMap<AnalyzedRelation, Boolean>());
    Multimap<AnalyzedRelation, Integer> splits = Multimaps.newSetMultimap(new IdentityHashMap<AnalyzedRelation, Collection<Integer>>(specs.size()), INT_SET_SUPPLIER);
    // to the remaining OrderBy in the correct order.
    for (Symbol symbol : orderBy.orderBySymbols()) {
        relations.clear();
        RelationCounter.INSTANCE.process(symbol, relations);
        if (relations.size() > 1 || // Outer Join requires post-order-by because the nested loop adds rows which affects ordering
        JoinPairs.isOuterRelation(relations.iterator().next().getQualifiedName(), joinPairs)) {
            remainingOrderBy = new RemainingOrderBy();
            break;
        }
    }
    Integer idx = 0;
    for (Symbol symbol : orderBy.orderBySymbols()) {
        // the join
        if (Aggregations.containsAggregation(symbol)) {
            continue;
        }
        relations.clear();
        RelationCounter.INSTANCE.process(symbol, relations);
        // sort again at the place where remainingOrderBy is applied.
        if (remainingOrderBy != null) {
            OrderBy newOrderBy = orderBy.subset(Collections.singletonList(idx));
            for (AnalyzedRelation rel : relations) {
                remainingOrderBy.addRelation(rel.getQualifiedName());
            }
            remainingOrderBy.addOrderBy(newOrderBy);
        } else {
            // push down
            splits.put(Iterables.getOnlyElement(relations), idx);
        }
        idx++;
    }
    // Process pushed down order by
    for (Map.Entry<AnalyzedRelation, Collection<Integer>> entry : splits.asMap().entrySet()) {
        AnalyzedRelation relation = entry.getKey();
        OrderBy newOrderBy = orderBy.subset(entry.getValue());
        QuerySpec spec = getSpec(relation);
        assert !spec.orderBy().isPresent() : "spec.orderBy() must not be present";
        spec.orderBy(newOrderBy);
        requiredForQuery.addAll(newOrderBy.orderBySymbols());
    }
}
Also used : OrderBy(io.crate.analyze.OrderBy) QuerySpec(io.crate.analyze.QuerySpec)

Example 2 with OrderBy

use of io.crate.analyze.OrderBy in project crate by crate.

the class RelationSplitter method processOutputs.

private void processOutputs() {
    FieldCollectingVisitor.Context context = new FieldCollectingVisitor.Context(specs.size());
    // declare all symbols from the remaining order by as required for query
    if (remainingOrderBy != null) {
        OrderBy orderBy = remainingOrderBy.orderBy();
        requiredForQuery.addAll(orderBy.orderBySymbols());
        // we need to add also the used symbols for query phase
        FieldCollectingVisitor.INSTANCE.process(orderBy.orderBySymbols(), context);
    }
    if (querySpec.where().hasQuery()) {
        FieldCollectingVisitor.INSTANCE.process(querySpec.where().query(), context);
    }
    // collect all fields from all join conditions
    FieldCollectingVisitor.INSTANCE.process(joinConditions, context);
    // set the limit and offset where possible
    Optional<Symbol> limit = querySpec.limit();
    if (limit.isPresent()) {
        Optional<Symbol> limitAndOffset = Limits.mergeAdd(limit, querySpec.offset());
        for (AnalyzedRelation rel : Sets.difference(specs.keySet(), context.fields.keySet())) {
            QuerySpec spec = specs.get(rel);
            spec.limit(limitAndOffset);
        }
    }
    // add all order by symbols to context outputs
    for (Map.Entry<AnalyzedRelation, QuerySpec> entry : specs.entrySet()) {
        if (entry.getValue().orderBy().isPresent()) {
            context.fields.putAll(entry.getKey(), entry.getValue().orderBy().get().orderBySymbols());
        }
    }
    // everything except the actual outputs is required for query
    requiredForQuery.addAll(context.fields.values());
    // capture items from the outputs
    canBeFetched = FetchFieldExtractor.process(querySpec.outputs(), context.fields);
    FieldCollectingVisitor.INSTANCE.process(querySpec.outputs(), context);
    // generate the outputs of the subSpecs
    for (Map.Entry<AnalyzedRelation, QuerySpec> entry : specs.entrySet()) {
        Collection<Symbol> fields = context.fields.get(entry.getKey());
        assert entry.getValue().outputs() == null : "entry.getValue().outputs() must not be null";
        entry.getValue().outputs(new ArrayList<>(fields));
    }
}
Also used : OrderBy(io.crate.analyze.OrderBy) QuerySpec(io.crate.analyze.QuerySpec)

Example 3 with OrderBy

use of io.crate.analyze.OrderBy in project crate by crate.

the class OrderedLuceneBatchIteratorBenchmark method createLuceneBatchIterator.

@Setup
public void createLuceneBatchIterator() throws Exception {
    IndexWriter iw = new IndexWriter(new RAMDirectory(), new IndexWriterConfig(new StandardAnalyzer()));
    dummyShardId = new ShardId("dummy", 1);
    columnName = "x";
    for (int i = 0; i < 10_000_000; i++) {
        Document doc = new Document();
        doc.add(new NumericDocValuesField(columnName, i));
        iw.addDocument(doc);
    }
    iw.commit();
    iw.forceMerge(1, true);
    indexSearcher = new IndexSearcher(DirectoryReader.open(iw, true));
    collectorContext = new CollectorContext(mock(IndexFieldDataService.class), new CollectorFieldsVisitor(0));
    fieldTypeLookup = column -> {
        IntegerFieldMapper.IntegerFieldType integerFieldType = new IntegerFieldMapper.IntegerFieldType();
        integerFieldType.setNames(new MappedFieldType.Names(column));
        return integerFieldType;
    };
    reference = new Reference(new ReferenceIdent(new TableIdent(null, "dummyTable"), columnName), RowGranularity.DOC, DataTypes.INTEGER);
    orderBy = new OrderBy(Collections.singletonList(reference), reverseFlags, nullsFirst);
}
Also used : OrderBy(io.crate.analyze.OrderBy) Reference(io.crate.metadata.Reference) TableIdent(io.crate.metadata.TableIdent) Document(org.apache.lucene.document.Document) IntegerFieldMapper(org.elasticsearch.index.mapper.core.IntegerFieldMapper) RAMDirectory(org.apache.lucene.store.RAMDirectory) ReferenceIdent(io.crate.metadata.ReferenceIdent) ShardId(org.elasticsearch.index.shard.ShardId) NumericDocValuesField(org.apache.lucene.document.NumericDocValuesField) IndexWriter(org.apache.lucene.index.IndexWriter) StandardAnalyzer(org.apache.lucene.analysis.standard.StandardAnalyzer) MappedFieldType(org.elasticsearch.index.mapper.MappedFieldType) CollectorContext(io.crate.operation.reference.doc.lucene.CollectorContext) IndexWriterConfig(org.apache.lucene.index.IndexWriterConfig)

Example 4 with OrderBy

use of io.crate.analyze.OrderBy in project crate by crate.

the class RelationSplitterTest method testSplitOrderByWith3RelationsButOutputsOnly2Relations.

@Test
public void testSplitOrderByWith3RelationsButOutputsOnly2Relations() throws Exception {
    QuerySpec querySpec = fromQuery("x = 1 and y = 2 and z = 3").limit(Optional.of(Literal.of(30)));
    List<Symbol> orderBySymbols = Arrays.asList(asSymbol("x"), asSymbol("y"), asSymbol("z"));
    OrderBy orderBy = new OrderBy(orderBySymbols, new boolean[] { false, false, false }, new Boolean[] { null, null, null });
    querySpec.orderBy(orderBy).limit(Optional.of((Symbol) Literal.of(20))).outputs(Arrays.asList(asSymbol("x"), asSymbol("y")));
    RelationSplitter splitter = split(querySpec);
    assertThat(querySpec, isSQL("SELECT doc.t1.x, doc.t2.y ORDER BY doc.t1.x, doc.t2.y, doc.t3.z LIMIT 20"));
    assertThat(splitter.remainingOrderBy().isPresent(), is(false));
    assertThat(splitter.getSpec(T3.TR_1), isSQL("SELECT doc.t1.x WHERE (doc.t1.x = 1) ORDER BY doc.t1.x LIMIT 20"));
    assertThat(splitter.getSpec(T3.TR_2), isSQL("SELECT doc.t2.y WHERE (true AND (doc.t2.y = 2)) ORDER BY doc.t2.y LIMIT 20"));
    assertThat(splitter.getSpec(T3.TR_3), isSQL("SELECT doc.t3.z WHERE (true AND (doc.t3.z = 3)) ORDER BY doc.t3.z LIMIT 20"));
}
Also used : OrderBy(io.crate.analyze.OrderBy) Symbol(io.crate.analyze.symbol.Symbol) QuerySpec(io.crate.analyze.QuerySpec) Test(org.junit.Test) CrateUnitTest(io.crate.test.integration.CrateUnitTest)

Example 5 with OrderBy

use of io.crate.analyze.OrderBy in project crate by crate.

the class LuceneOrderedDocCollectorTest method testNextPageQueryWithLastCollectedNullValue.

@Test
public void testNextPageQueryWithLastCollectedNullValue() throws Exception {
    FieldDoc fieldDoc = new FieldDoc(1, 0, new Object[] { null });
    OrderBy orderBy = new OrderBy(Collections.<Symbol>singletonList(REFERENCE), new boolean[] { false }, new Boolean[] { null });
    Object missingValue = LuceneMissingValue.missingValue(orderBy, 0);
    LuceneOrderedDocCollector.nextPageQuery(fieldDoc, orderBy, new Object[] { missingValue }, name -> valueFieldType);
}
Also used : OrderBy(io.crate.analyze.OrderBy) Test(org.junit.Test) RandomizedTest(com.carrotsearch.randomizedtesting.RandomizedTest)

Aggregations

OrderBy (io.crate.analyze.OrderBy)64 Test (org.junit.Test)29 Symbol (io.crate.expression.symbol.Symbol)16 ArrayList (java.util.ArrayList)14 QuerySpec (io.crate.analyze.QuerySpec)13 List (java.util.List)13 Row (io.crate.data.Row)12 Reference (io.crate.metadata.Reference)10 Nullable (javax.annotation.Nullable)9 QueriedDocTable (io.crate.analyze.relations.QueriedDocTable)8 CrateDummyClusterServiceUnitTest (io.crate.test.integration.CrateDummyClusterServiceUnitTest)8 Map (java.util.Map)8 ShardId (org.elasticsearch.index.shard.ShardId)8 Symbol (io.crate.analyze.symbol.Symbol)7 InputFactory (io.crate.expression.InputFactory)7 RelationName (io.crate.metadata.RelationName)7 WindowDefinition (io.crate.analyze.WindowDefinition)6 TransactionContext (io.crate.metadata.TransactionContext)6 DataType (io.crate.types.DataType)6 Lists2 (io.crate.common.collections.Lists2)5