LOG.debug("Examining " + join_node);
// Check whether the chain below this node is
// RECIEVE -> SEND -> SCAN
assert (join_node.getChildPlanNodeCount() >= 1);
AbstractPlanNode child = join_node.getChild(0);
if (debug.val)
LOG.debug(join_node + " -> " + child);
if (child instanceof ReceivePlanNode) {
ReceivePlanNode recv_node = (ReceivePlanNode) child;
SendPlanNode send_node = (SendPlanNode) child.getChild(0);
List<AbstractPlanNode> children = send_node.getChildren();
assert (children != null);
if (children.size() > 1)
continue;
if (children.get(0).getChildPlanNodeCount() > 0)
continue;
if ((children.get(0) instanceof AbstractScanPlanNode) == false)
continue;
AbstractPlanNode leaf_node = children.get(0);
assert (leaf_node instanceof AbstractScanPlanNode);
Collection<Table> leaf_tables = CatalogUtil.getReferencedTablesForPlanNode(state.catalog_db, leaf_node);
assert (leaf_tables.size() == 1);
Table leaf_tbl = CollectionUtil.first(leaf_tables);
Collection<Table> join_tables = CatalogUtil.getReferencedTablesForPlanNode(state.catalog_db, join_node);
Table join_tbl = null;
for (Table catalog_tbl : join_tables) {
if (catalog_tbl.equals(leaf_tbl) == false) {
join_tbl = catalog_tbl;
break;
}
} // FOR
assert (join_tbl != null);
// If either table is replicated, then the leaf scan should be linked
// directly with the Join PlanNode
if (join_tbl.getIsreplicated() || leaf_tbl.getIsreplicated()) {
AbstractPlanNode parent = join_node.getParent(0);
assert (parent != null);
parent.clearChildren();
parent.addAndLinkChild(recv_node);
state.markDirty(parent);
state.markDirty(recv_node);
join_node.clearParents();
join_node.clearChildren();
leaf_node.clearParents();
join_node.addAndLinkChild(leaf_node);
state.markDirty(join_node);
state.markDirty(leaf_node);
// HACK: If the parent is a ProjectionPlanNode, then we'll want
// to duplicate it so that we make sure that our original
// SEND/RECIEVE nodes have the right offsets
if (parent instanceof ProjectionPlanNode) {
AbstractPlanNode parent_clone = null;
try {
parent_clone = (AbstractPlanNode) parent.clone(false, false);
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
assert (parent_clone != null);
assert (parent != parent_clone);
parent_clone.addAndLinkChild(join_node);
send_node.clearChildren();
send_node.addAndLinkChild(parent_clone);
} else {
send_node.clearChildren();
send_node.addAndLinkChild(join_node);