use of io.crate.execution.dsl.phases.RoutedCollectPhase in project crate by crate.
the class GroupByPlannerTest method testGroupByOnNodeLevel.
@Test
public void testGroupByOnNodeLevel() throws Exception {
var e = SQLExecutor.builder(clusterService, 2, RandomizedTest.getRandom(), List.of()).build();
Collect collect = e.plan("select count(*), name from sys.nodes group by name");
assertThat("number of nodeIds must be 1, otherwise there must be a merge", collect.resultDescription().nodeIds().size(), is(1));
RoutedCollectPhase collectPhase = ((RoutedCollectPhase) collect.collectPhase());
assertThat(collectPhase.projections(), contains(instanceOf(GroupProjection.class), instanceOf(EvalProjection.class)));
GroupProjection groupProjection = (GroupProjection) collectPhase.projections().get(0);
assertThat(Symbols.typeView(groupProjection.outputs()), contains(is(DataTypes.STRING), is(DataTypes.LONG)));
assertThat(Symbols.typeView(collectPhase.projections().get(1).outputs()), contains(is(DataTypes.LONG), is(DataTypes.STRING)));
}
use of io.crate.execution.dsl.phases.RoutedCollectPhase in project crate by crate.
the class CollectTest method test.
@Test
public void test() throws Exception {
var e = SQLExecutor.builder(clusterService).addTable("CREATE TABLE t (x int)").build();
TableStats tableStats = new TableStats();
PlannerContext plannerCtx = e.getPlannerContext(clusterService.state());
ProjectionBuilder projectionBuilder = new ProjectionBuilder(e.nodeCtx);
QueriedSelectRelation analyzedRelation = e.analyze("SELECT 123 AS alias, 456 AS alias2 FROM t ORDER BY alias, 2");
LogicalPlanner logicalPlanner = new LogicalPlanner(e.nodeCtx, tableStats, () -> clusterService.state().nodes().getMinNodeVersion());
LogicalPlan operator = logicalPlanner.plan(analyzedRelation, plannerCtx);
ExecutionPlan build = operator.build(plannerCtx, Set.of(), projectionBuilder, -1, 0, null, null, Row.EMPTY, SubQueryResults.EMPTY);
assertThat((((RoutedCollectPhase) ((io.crate.planner.node.dql.Collect) build).collectPhase())).orderBy(), is(nullValue()));
}
use of io.crate.execution.dsl.phases.RoutedCollectPhase in project crate by crate.
the class ShardCollectSource method getIterator.
@Override
public CompletableFuture<BatchIterator<Row>> getIterator(TransactionContext txnCtx, CollectPhase phase, CollectTask collectTask, boolean supportMoveToStart) {
RoutedCollectPhase collectPhase = (RoutedCollectPhase) phase;
String localNodeId = clusterService.localNode().getId();
Projectors projectors = new Projectors(collectPhase.projections(), collectPhase.jobId(), collectTask.txnCtx(), collectTask.getRamAccounting(), collectTask.memoryManager(), sharedProjectorFactory);
boolean requireMoveToStartSupport = supportMoveToStart && !projectors.providesIndependentScroll();
if (collectPhase.maxRowGranularity() == RowGranularity.SHARD) {
return CompletableFuture.completedFuture(projectors.wrap(InMemoryBatchIterator.of(getShardsIterator(collectTask.txnCtx(), collectPhase, localNodeId), SentinelRow.SENTINEL, true)));
}
OrderBy orderBy = collectPhase.orderBy();
if (collectPhase.maxRowGranularity() == RowGranularity.DOC && orderBy != null) {
return createMultiShardScoreDocCollector(collectPhase, requireMoveToStartSupport, collectTask, localNodeId).thenApply(projectors::wrap);
}
boolean hasShardProjections = Projections.hasAnyShardProjections(collectPhase.projections());
Map<String, IntIndexedContainer> indexShards = collectPhase.routing().locations().get(localNodeId);
List<CompletableFuture<BatchIterator<Row>>> iterators = indexShards == null ? Collections.emptyList() : getIterators(collectTask, collectPhase, requireMoveToStartSupport, indexShards);
final CompletableFuture<BatchIterator<Row>> result;
switch(iterators.size()) {
case 0:
result = CompletableFuture.completedFuture(InMemoryBatchIterator.empty(SentinelRow.SENTINEL));
break;
case 1:
result = iterators.get(0);
break;
default:
if (hasShardProjections) {
// use AsyncCompositeBatchIterator for multi-threaded loadNextBatch
// in order to process shard-based projections concurrently
// noinspection unchecked
result = CompletableFutures.allAsList(iterators).thenApply(its -> CompositeBatchIterator.asyncComposite(executor, availableThreads, its.toArray(new BatchIterator[0])));
} else {
// noinspection unchecked
result = CompletableFutures.allAsList(iterators).thenApply(its -> CompositeBatchIterator.seqComposite(its.toArray(new BatchIterator[0])));
}
}
return result.thenApply(it -> projectors.wrap(it));
}
use of io.crate.execution.dsl.phases.RoutedCollectPhase in project crate by crate.
the class RemoteCollectorFactory method createCollector.
/**
* create a RemoteCollector
* The RemoteCollector will collect data from another node using a wormhole as if it was collecting on this node.
* <p>
* This should only be used if a shard is not available on the current node due to a relocation
*/
public CompletableFuture<BatchIterator<Row>> createCollector(ShardId shardId, RoutedCollectPhase collectPhase, CollectTask collectTask, ShardCollectorProviderFactory shardCollectorProviderFactory) {
ShardStateObserver shardStateObserver = new ShardStateObserver(clusterService);
CompletableFuture<ShardRouting> shardBecameActive = shardStateObserver.waitForActiveShard(shardId);
Runnable onClose = () -> {
};
Consumer<Throwable> kill = killReason -> {
shardBecameActive.cancel(true);
shardBecameActive.completeExceptionally(killReason);
};
return shardBecameActive.thenApply(activePrimaryRouting -> CollectingBatchIterator.newInstance(onClose, kill, () -> retrieveRows(activePrimaryRouting, collectPhase, collectTask, shardCollectorProviderFactory), true));
}
use of io.crate.execution.dsl.phases.RoutedCollectPhase in project crate by crate.
the class SystemCollectSource method getIterator.
@Override
public CompletableFuture<BatchIterator<Row>> getIterator(TransactionContext txnCtx, CollectPhase phase, CollectTask collectTask, boolean supportMoveToStart) {
RoutedCollectPhase collectPhase = (RoutedCollectPhase) phase;
Map<String, Map<String, IntIndexedContainer>> locations = collectPhase.routing().locations();
String table = Iterables.getOnlyElement(locations.get(clusterService.localNode().getId()).keySet());
RelationName relationName = RelationName.fromIndexName(table);
StaticTableDefinition<?> tableDefinition = tableDefinition(relationName);
User user = requireNonNull(userLookup.findUser(txnCtx.sessionSettings().userName()), "User who invoked a statement must exist");
return CompletableFuture.completedFuture(CollectingBatchIterator.newInstance(() -> {
}, // If data is already local, then `CollectingBatchIterator` takes care of kill handling.
t -> {
}, () -> tableDefinition.retrieveRecords(txnCtx, user).thenApply(records -> recordsToRows(collectPhase, collectTask.txnCtx(), tableDefinition.getReferenceResolver(), supportMoveToStart, records)), tableDefinition.involvesIO()));
}
Aggregations