case NodeConstants.Types.TUPLE_LIMIT:
case NodeConstants.Types.DUP_REMOVE:
case NodeConstants.Types.SORT:
if (root.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
//add missing sort columns
OrderBy elements = (OrderBy) root.getProperty(NodeConstants.Info.SORT_ORDER);
outputElements = new ArrayList<SingleElementSymbol>(outputElements);
boolean hasUnrelated = false;
for (OrderByItem item : elements.getOrderByItems()) {
if (item.getExpressionPosition() == -1) {
int index = outputElements.indexOf(item.getSymbol());
if (index != -1) {
item.setExpressionPosition(index);
} else {
hasUnrelated = true;
outputElements.add(item.getSymbol());
}
}
}
if (!hasUnrelated) {
root.setProperty(NodeConstants.Info.UNRELATED_SORT, false);
}
}
assignOutputElements(root.getLastChild(), outputElements, metadata, capFinder, rules, analysisRecord, context);
break;
case NodeConstants.Types.SOURCE: {
outputElements = (List<SingleElementSymbol>)determineSourceOutput(root, outputElements, metadata, capFinder);
root.setProperty(NodeConstants.Info.OUTPUT_COLS, outputElements);
List<SingleElementSymbol> childElements = filterVirtualElements(root, outputElements, metadata);
assignOutputElements(root.getFirstChild(), childElements, metadata, capFinder, rules, analysisRecord, context);
break;
}
case NodeConstants.Types.SET_OP: {
for (PlanNode childNode : root.getChildren()) {
PlanNode projectNode = NodeEditor.findNodePreOrder(childNode, NodeConstants.Types.PROJECT);
List<SingleElementSymbol> projectCols = (List<SingleElementSymbol>)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS);
assignOutputElements(childNode, projectCols, metadata, capFinder, rules, analysisRecord, context);
}
break;
}
default: {
if (root.getType() == NodeConstants.Types.PROJECT) {
GroupSymbol intoGroup = (GroupSymbol)root.getProperty(NodeConstants.Info.INTO_GROUP);
if (intoGroup != null) { //if this is a project into, treat the nodes under the source as a new plan root
PlanNode intoRoot = NodeEditor.findNodePreOrder(root, NodeConstants.Types.SOURCE);
execute(intoRoot.getFirstChild(), metadata, capFinder, rules, analysisRecord, context);
return;
}
List<SingleElementSymbol> projectCols = outputElements;
boolean modifiedProject = false;
PlanNode sortNode = NodeEditor.findParent(root, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
if (sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
//if this is the initial rule run, remove unrelated order before changing the project cols
if (rules.contains(RuleConstants.ASSIGN_OUTPUT_ELEMENTS)) {
OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
projectCols = new ArrayList<SingleElementSymbol>(projectCols);
for (OrderByItem item : elements.getOrderByItems()) {
if (item.getExpressionPosition() == -1) {
projectCols.remove(item.getSymbol());
}
}
} else {