tableGroup.getOutput().replaceInput(tableGroup, joins);
}
}
protected PlanNode joinBranches(TableGroupJoinTree tableGroup) {
TableGroupJoinNode rootTable = tableGroup.getRoot();
PlanNode scan = tableGroup.getScan();
if (scan instanceof IndexScan) {
IndexScan indexScan = (IndexScan)scan;
if (indexScan.isCovering())
return indexScan;
}
Set<TableSource> requiredTables = null;
if (scan instanceof BaseScan) {
requiredTables = ((BaseScan)scan).getRequiredTables();
}
markBranches(tableGroup, requiredTables);
top:
if (scan instanceof JoinTreeScan) {
TableSource indexTable = ((JoinTreeScan)scan).getLeafMostTable();
TableGroupJoinNode leafTable = rootTable.findTable(indexTable);
assert (leafTable != null) : scan;
List<TableSource> ancestors = new ArrayList<>();
pendingTableSources(leafTable, rootTable, ancestors);
if (isParent(leafTable)) {
if (ancestors.remove(indexTable))
setPending(leafTable); // Changed from ancestor to branch.
List<TableSource> tables = new ArrayList<>();
scan = new BranchLookup(scan, indexTable.getTable(), tables);
leafTable = singleBranchPending(leafTable, tables);
}
else if (!isRequired(leafTable)) {
// Don't need the table that the index points to or
// anything beneath it; might be able to jump to a
// side branch.
PlanNode sideScan = trySideBranch(scan, leafTable, rootTable,
indexTable, ancestors);
if (sideScan != null) {
scan = sideScan;
break top;
}
}
if (!ancestors.isEmpty())
scan = new AncestorLookup(scan, indexTable, ancestors);
scan = flatten(scan, leafTable, rootTable);
scan = fillSideBranches(scan, leafTable, rootTable);
}
else if (scan instanceof GroupScan) {
GroupScan groupScan = (GroupScan)scan;
List<TableSource> tables = new ArrayList<>();
groupScan.setTables(tables);
scan = fillBranch(scan, tables, rootTable, rootTable, rootTable);
}
else if (scan instanceof GroupLoopScan) {
GroupLoopScan groupLoop = (GroupLoopScan)scan;
TableSource outsideTable = groupLoop.getOutsideTable();
TableSource insideTable = groupLoop.getInsideTable();
if (groupLoop.isInsideParent()) {
TableGroupJoinNode parent = rootTable.findTable(groupLoop.getInsideTable());
assert (parent != null) : groupLoop;
List<TableSource> ancestors = new ArrayList<>();
pendingTableSources(parent, rootTable, ancestors);
scan = new AncestorLookup(scan, outsideTable, ancestors);
scan = flatten(scan, parent, rootTable);
scan = fillGroupLoopBranches(scan, parent, rootTable);
}
else {
assert (groupLoop.getInsideTable() == rootTable.getTable());
List<TableSource> tables = new ArrayList<>();
scan = new BranchLookup(scan, outsideTable.getTable(), insideTable.getTable(), tables);
scan = fillBranch(scan, tables, rootTable, rootTable, rootTable);
}
}
else if (scan instanceof FullTextScan) {
FullTextScan textScan = (FullTextScan)scan;
TableSource indexSource = textScan.getIndexTable();
TableGroupJoinNode indexTable = rootTable.findTable(indexSource);
assert (indexTable != null) : textScan;
List<TableSource> ancestors = new ArrayList<>();
pendingTableSources(indexTable, rootTable, ancestors);
if (isParent(indexTable)) {
if (ancestors.remove(indexSource))