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());
}
}
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));
}
}
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);
}
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"));
}
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);
}
Aggregations