break;
case NodeConstants.Types.SORT:
case NodeConstants.Types.DUP_REMOVE:
SortNode sortNode = new SortNode(getID());
OrderBy orderBy = (OrderBy) node.getProperty(NodeConstants.Info.SORT_ORDER);
if (orderBy != null) {
sortNode.setSortElements(orderBy.getOrderByItems());
}
if (node.getType() == NodeConstants.Types.DUP_REMOVE) {
sortNode.setMode(Mode.DUP_REMOVE);
} else if (node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL)) {
sortNode.setMode(Mode.DUP_REMOVE_SORT);
}
processNode = sortNode;
break;
case NodeConstants.Types.GROUP:
GroupingNode gnode = new GroupingNode(getID());
gnode.setGroupingElements( (List) node.getProperty(NodeConstants.Info.GROUP_COLS) );
gnode.setRemoveDuplicates(node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL));
processNode = gnode;
break;
case NodeConstants.Types.SOURCE:
SymbolMap symbolMap = (SymbolMap) node.getProperty(NodeConstants.Info.SYMBOL_MAP);
if(symbolMap != null) {
PlanNode child = node.getLastChild();
if (node.getParent().getType() != NodeConstants.Types.PROJECT || node.getParent().getProperty(NodeConstants.Info.INTO_GROUP) == null) {
if (child.getType() == NodeConstants.Types.PROJECT) {
//update the project cols based upon the original output
child.setProperty(NodeConstants.Info.PROJECT_COLS, child.getProperty(NodeConstants.Info.OUTPUT_COLS));
}
child.setProperty(NodeConstants.Info.OUTPUT_COLS, node.getProperty(NodeConstants.Info.OUTPUT_COLS));
}
}
Object source = node.getProperty(NodeConstants.Info.TABLE_FUNCTION);
if (source instanceof XMLTable) {
XMLTable xt = (XMLTable)source;
XMLTableNode xtn = new XMLTableNode(getID());
//we handle the projection filtering once here rather than repeating the
//path analysis on a per plan basis
updateGroupName(node, xt);
Map elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
List cols = (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
ArrayList<XMLColumn> filteredColumns = new ArrayList<XMLColumn>(projectionIndexes.length);
for (int col : projectionIndexes) {
filteredColumns.add(xt.getColumns().get(col));
}
xt.getXQueryExpression().useDocumentProjection(filteredColumns, analysisRecord);
xtn.setProjectedColumns(filteredColumns);
xtn.setTable(xt);
processNode = xtn;
break;
}
if (source instanceof TextTable) {
TextTableNode ttn = new TextTableNode(getID());
TextTable tt = (TextTable)source;
updateGroupName(node, tt);
ttn.setTable(tt);
processNode = ttn;
break;
}
if (source instanceof ArrayTable) {
ArrayTableNode atn = new ArrayTableNode(getID());
ArrayTable at = (ArrayTable)source;
updateGroupName(node, at);
atn.setTable(at);
processNode = atn;
break;
}
return null;
case NodeConstants.Types.SET_OP:
Operation setOp = (Operation) node.getProperty(NodeConstants.Info.SET_OPERATION);
boolean useAll = ((Boolean) node.getProperty(NodeConstants.Info.USE_ALL)).booleanValue();
if(setOp == Operation.UNION) {
RelationalNode unionAllNode = new UnionAllNode(getID());
if(useAll) {
processNode = unionAllNode;
} else {
SortNode sNode = new SortNode(getID());
boolean onlyDupRemoval = node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL);
sNode.setMode(onlyDupRemoval?Mode.DUP_REMOVE:Mode.DUP_REMOVE_SORT);
processNode = sNode;
unionAllNode.setElements( (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS) );
processNode.addChild(unionAllNode);
}