CapabilitiesFinder capFinder, RulePushSelectCriteria rpsc,
Expression depExpr, LinkedList<Expression> depExpressions)
throws QueryPlannerException, TeiidComponentException {
LinkedList<PlanNode> targets = new LinkedList<PlanNode>();
LinkedList<PlanNode> critNodes = new LinkedList<PlanNode>();
critNodes.add(RelationalPlanner.createSelectNode(new DependentSetCriteria(depExpr, null), false));
LinkedList<PlanNode> initialTargets = new LinkedList<PlanNode>();
initialTargets.add(dependentNode);
while (!critNodes.isEmpty()) {
PlanNode critNode = critNodes.remove();
PlanNode initial = initialTargets.remove();
if (critNode.getGroups().isEmpty()) {
//TODO: we need to project constants up through a plan to avoid this case
continue;
}
PlanNode sourceNode = FrameUtil.findOriginatingNode(initial, critNode.getGroups());
PlanNode target = sourceNode;
if (initial != sourceNode) {
target = rpsc.examinePath(initial, sourceNode, metadata, capFinder);
}
if (target != sourceNode || (sourceNode.getType() == NodeConstants.Types.SOURCE && sourceNode.getChildCount() == 0)) {
targets.add(target);
DependentSetCriteria dsc = (DependentSetCriteria)critNode.getProperty(Info.SELECT_CRITERIA);
depExpressions.add(dsc.getExpression());
continue;
}
if (sourceNode.getType() == NodeConstants.Types.SOURCE) {
PlanNode child = sourceNode.getFirstChild();
child = FrameUtil.findOriginatingNode(child, child.getGroups());
if (child != null && child.getType() == NodeConstants.Types.SET_OP) {
targets.add(target);
DependentSetCriteria dsc = (DependentSetCriteria)critNode.getProperty(Info.SELECT_CRITERIA);
depExpressions.add(dsc.getExpression());
//TODO: we need better handling for set op situations
continue;
}
if (!rpsc.pushAcrossFrame(sourceNode, critNode, metadata)) {
targets.add(target);
DependentSetCriteria dsc = (DependentSetCriteria)critNode.getProperty(Info.SELECT_CRITERIA);
depExpressions.add(dsc.getExpression());
}
List<PlanNode> createdNodes = rpsc.getCreatedNodes();
for (PlanNode planNode : createdNodes) {
critNodes.add(planNode);
initialTargets.add(planNode.getFirstChild());