use of io.crate.analyze.OrderBy in project crate by crate.
the class AbstractWindowFunctionTest method assertEvaluate.
@SuppressWarnings("unchecked")
protected <T> void assertEvaluate(String functionExpression, Matcher<T> expectedValue, List<ColumnIdent> rowsColumnDescription, Object[]... inputRows) throws Throwable {
performInputSanityChecks(inputRows);
Symbol normalizedFunctionSymbol = sqlExpressions.normalize(sqlExpressions.asSymbol(functionExpression));
assertThat(normalizedFunctionSymbol, instanceOf(io.crate.expression.symbol.WindowFunction.class));
var windowFunctionSymbol = (io.crate.expression.symbol.WindowFunction) normalizedFunctionSymbol;
ReferenceResolver<InputCollectExpression> referenceResolver = r -> new InputCollectExpression(rowsColumnDescription.indexOf(r.column()));
var sourceSymbols = Lists2.map(rowsColumnDescription, x -> sqlExpressions.normalize(sqlExpressions.asSymbol(x.sqlFqn())));
ensureInputRowsHaveCorrectType(sourceSymbols, inputRows);
var argsCtx = inputFactory.ctxForRefs(txnCtx, referenceResolver);
argsCtx.add(windowFunctionSymbol.arguments());
FunctionImplementation impl = sqlExpressions.nodeCtx.functions().getQualified(windowFunctionSymbol, txnCtx.sessionSettings().searchPath());
assert impl instanceof WindowFunction || impl instanceof AggregationFunction : "Got " + impl + " but expected a window function";
WindowFunction windowFunctionImpl;
if (impl instanceof AggregationFunction) {
windowFunctionImpl = new AggregateToWindowFunctionAdapter((AggregationFunction) impl, new ExpressionsInput<>(Literal.BOOLEAN_TRUE, List.of()), Version.CURRENT, RamAccounting.NO_ACCOUNTING, memoryManager, Version.CURRENT);
} else {
windowFunctionImpl = (WindowFunction) impl;
}
int numCellsInSourceRows = inputRows[0].length;
var windowDef = windowFunctionSymbol.windowDefinition();
var partitionOrderBy = windowDef.partitions().isEmpty() ? null : new OrderBy(windowDef.partitions());
Comparator<Object[]> cmpOrderBy = createComparator(() -> inputFactory.ctxForRefs(txnCtx, referenceResolver), windowDef.orderBy());
InputColumns.SourceSymbols inputColSources = new InputColumns.SourceSymbols(sourceSymbols);
var mappedWindowDef = windowDef.map(s -> InputColumns.create(s, inputColSources));
BatchIterator<Row> iterator = WindowFunctionBatchIterator.of(InMemoryBatchIterator.of(Arrays.stream(inputRows).map(RowN::new).collect(Collectors.toList()), SENTINEL, true), new IgnoreRowAccounting(), WindowProjector.createComputeStartFrameBoundary(numCellsInSourceRows, txnCtx, sqlExpressions.nodeCtx, mappedWindowDef, cmpOrderBy), WindowProjector.createComputeEndFrameBoundary(numCellsInSourceRows, txnCtx, sqlExpressions.nodeCtx, mappedWindowDef, cmpOrderBy), createComparator(() -> inputFactory.ctxForRefs(txnCtx, referenceResolver), partitionOrderBy), cmpOrderBy, numCellsInSourceRows, () -> 1, Runnable::run, List.of(windowFunctionImpl), argsCtx.expressions(), new Boolean[] { windowFunctionSymbol.ignoreNulls() }, argsCtx.topLevelInputs().toArray(new Input[0]));
List<Object> actualResult;
try {
actualResult = BatchIterators.collect(iterator, Collectors.mapping(row -> row.get(numCellsInSourceRows), Collectors.toList())).get(5, TimeUnit.SECONDS);
} catch (ExecutionException e) {
throw e.getCause();
}
assertThat((T) actualResult, expectedValue);
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class RoutedCollectPhaseTest method testNormalizeDoesNotRemoveOrderBy.
@Test
public void testNormalizeDoesNotRemoveOrderBy() throws Exception {
Symbol toInt10 = CastFunctionResolver.generateCastFunction(Literal.of(10L), DataTypes.INTEGER);
RoutedCollectPhase collect = new RoutedCollectPhase(UUID.randomUUID(), 1, "collect", new Routing(Collections.emptyMap()), RowGranularity.DOC, Collections.singletonList(toInt10), Collections.emptyList(), WhereClause.MATCH_ALL.queryOrFallback(), DistributionInfo.DEFAULT_SAME_NODE);
collect.orderBy(new OrderBy(Collections.singletonList(toInt10)));
EvaluatingNormalizer normalizer = EvaluatingNormalizer.functionOnlyNormalizer(nodeCtx);
RoutedCollectPhase normalizedCollect = collect.normalize(normalizer, new CoordinatorTxnCtx(SessionContext.systemSessionContext()));
assertThat(normalizedCollect.orderBy(), notNullValue());
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class PositionalOrderByTest method testNewOutputMapping.
@Test
public void testNewOutputMapping() throws Exception {
List<Symbol> oldOutputs = Arrays.asList(ref("a"), ref("b"), ref("c"), ref("d"));
List<Symbol> newOutputs = Arrays.asList(ref("b"), ref("c"), ref("d"), ref("a"));
OrderBy orderBy = new OrderBy(Arrays.asList(ref("a"), ref("c"), ref("b")), new boolean[] { true, false, true }, new boolean[] { true, false, false });
PositionalOrderBy positionalOrderBy = PositionalOrderBy.of(orderBy, oldOutputs);
PositionalOrderBy newOrderBy = positionalOrderBy.tryMapToNewOutputs(oldOutputs, newOutputs);
PositionalOrderBy expected = PositionalOrderBy.of(orderBy, newOutputs);
assertThat(newOrderBy.indices(), Matchers.is(expected.indices()));
assertThat(newOrderBy.reverseFlags(), Matchers.is(expected.reverseFlags()));
assertThat(newOrderBy.nullsFirst(), Matchers.is(expected.nullsFirst()));
}
use of io.crate.analyze.OrderBy in project crate by crate.
the class OrderByAnalyzerTest method analyzeSortItems.
@Test
public void analyzeSortItems() {
List<SortItem> sortItems = new ArrayList<>(2);
QualifiedName tx = QualifiedName.of("t", "x");
SortItem firstSort = new SortItem(new QualifiedNameReference(tx), SortItem.Ordering.ASCENDING, SortItem.NullOrdering.FIRST);
sortItems.add(firstSort);
QualifiedName ty = QualifiedName.of("t", "y");
SortItem second = new SortItem(new QualifiedNameReference(ty), SortItem.Ordering.DESCENDING, SortItem.NullOrdering.LAST);
sortItems.add(second);
OrderBy orderBy = OrderyByAnalyzer.analyzeSortItems(sortItems, e -> Literal.of(((QualifiedNameReference) e).getName().toString()));
assertThat(orderBy, is(notNullValue()));
List<Symbol> orderBySymbols = orderBy.orderBySymbols();
assertThat(orderBySymbols.size(), is(2));
assertThat(orderBySymbols.get(0), SymbolMatchers.isLiteral("t.x"));
assertThat(orderBySymbols.get(1), SymbolMatchers.isLiteral("t.y"));
boolean[] reverseFlags = orderBy.reverseFlags();
assertThat(reverseFlags.length, is(2));
assertThat(reverseFlags[0], is(false));
assertThat(reverseFlags[1], is(true));
boolean[] nullsFirst = orderBy.nullsFirst();
assertThat(nullsFirst.length, is(2));
assertThat(nullsFirst[0], is(true));
assertThat(nullsFirst[1], is(false));
}
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