// The probe key channels will be handed to the index according to probeSymbol order
Map<Symbol, Input> probeKeyLayout = new HashMap<>();
for (int i = 0; i < probeSymbols.size(); i++) {
// Duplicate symbols can appear and we only need to take take one of the Inputs
probeKeyLayout.put(probeSymbols.get(i), new Input(i));
}
// Plan the index source side
SetMultimap<Symbol, Input> indexLookupToProbeInput = mapIndexSourceLookupSymbolToProbeKeyInput(node, probeKeyLayout);
LocalExecutionPlanContext indexContext = context.createIndexSourceSubContext(new IndexSourceContext(indexLookupToProbeInput));
PhysicalOperation indexSource = node.getIndexSource().accept(this, indexContext);
List<Integer> indexChannels = getChannelsForSymbols(indexSymbols, indexSource.getLayout());
PagesIndexBuilderOperatorFactory pagesIndexOutput = new PagesIndexBuilderOperatorFactory(
indexContext.getNextOperatorId(),
indexSource.getTypes()
);
DriverFactory indexBuildDriverFactory = new DriverFactory(
indexContext.isInputDriver(),
false,
ImmutableList.<OperatorFactory>builder()
.addAll(indexSource.getOperatorFactories())
.add(pagesIndexOutput)
.build());
IndexLookupSourceSupplier indexLookupSourceSupplier = new IndexLookupSourceSupplier(
indexChannels,
indexSource.getTypes(),
indexContext.getNextOperatorId(),
indexBuildDriverFactory,
pagesIndexOutput);
ImmutableMap.Builder<Symbol, Input> outputMappings = ImmutableMap.builder();
outputMappings.putAll(probeSource.getLayout());
// inputs from index side of the join are laid out following the input from the probe side,
// so adjust the channel ids but keep the field layouts intact
int offset = probeSource.getTypes().size();
for (Map.Entry<Symbol, Input> entry : indexSource.getLayout().entrySet()) {
Input input = entry.getValue();
outputMappings.put(entry.getKey(), new Input(offset + input.getChannel()));
}
OperatorFactory lookupJoinOperatorFactory;
switch (node.getType()) {
case INNER: