}
protected RelationalNode convertNode(PlanNode node)
throws QueryPlannerException, TeiidComponentException {
RelationalNode processNode = null;
switch(node.getType()) {
case NodeConstants.Types.PROJECT:
GroupSymbol intoGroup = (GroupSymbol) node.getProperty(NodeConstants.Info.INTO_GROUP);
if(intoGroup != null) {
try {
Insert insert = (Insert)node.getFirstChild().getProperty(Info.VIRTUAL_COMMAND);
List<ElementSymbol> allIntoElements = insert.getVariables();
Object groupID = intoGroup.getMetadataID();
Object modelID = metadata.getModelID(groupID);
String modelName = metadata.getFullName(modelID);
if (metadata.isVirtualGroup(groupID)) {
InsertPlanExecutionNode ipen = new InsertPlanExecutionNode(getID(), metadata);
ipen.setProcessorPlan((ProcessorPlan)node.getFirstChild().getProperty(Info.PROCESSOR_PLAN));
ipen.setReferences(insert.getValues());
processNode = ipen;
} else {
ProjectIntoNode pinode = new ProjectIntoNode(getID());
pinode.setIntoGroup(intoGroup);
pinode.setIntoElements(allIntoElements);
pinode.setModelName(modelName);
processNode = pinode;
SourceCapabilities caps = capFinder.findCapabilities(modelName);
if (caps.supportsCapability(Capability.INSERT_WITH_ITERATOR)) {
pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.ITERATOR);
} else if (caps.supportsCapability(Capability.BULK_UPDATE)) {
pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.BULK);
} else if (caps.supportsCapability(Capability.BATCHED_UPDATES)) {
pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.BATCH);
} else {
pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.SINGLE);
}
}
} catch(QueryMetadataException e) {
throw new TeiidComponentException(e);
}
} else {
List symbols = (List) node.getProperty(NodeConstants.Info.PROJECT_COLS);
ProjectNode pnode = new ProjectNode(getID());
pnode.setSelectSymbols(symbols);
processNode = pnode;
}
break;
case NodeConstants.Types.JOIN:
JoinType jtype = (JoinType) node.getProperty(NodeConstants.Info.JOIN_TYPE);
JoinStrategyType stype = (JoinStrategyType) node.getProperty(NodeConstants.Info.JOIN_STRATEGY);
JoinNode jnode = new JoinNode(getID());
jnode.setJoinType(jtype);
jnode.setLeftDistinct(node.hasBooleanProperty(NodeConstants.Info.IS_LEFT_DISTINCT));
jnode.setRightDistinct(node.hasBooleanProperty(NodeConstants.Info.IS_RIGHT_DISTINCT));
List joinCrits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
String depValueSource = (String) node.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE);
SortOption leftSort = (SortOption)node.getProperty(NodeConstants.Info.SORT_LEFT);
if(stype == JoinStrategyType.MERGE || stype == JoinStrategyType.ENHANCED_SORT) {
MergeJoinStrategy mjStrategy = null;
if (stype.equals(JoinStrategyType.ENHANCED_SORT)) {
mjStrategy = new EnhancedSortMergeJoinStrategy(leftSort, (SortOption)node.getProperty(NodeConstants.Info.SORT_RIGHT));
} else {
mjStrategy = new MergeJoinStrategy(leftSort, (SortOption)node.getProperty(NodeConstants.Info.SORT_RIGHT), false);
}
jnode.setJoinStrategy(mjStrategy);
List leftExpressions = (List) node.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS);
List rightExpressions = (List) node.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS);
jnode.setJoinExpressions(leftExpressions, rightExpressions);
joinCrits = (List) node.getProperty(NodeConstants.Info.NON_EQUI_JOIN_CRITERIA);
} else if (stype == JoinStrategyType.NESTED_TABLE) {
NestedTableJoinStrategy ntjStrategy = new NestedTableJoinStrategy();
jnode.setJoinStrategy(ntjStrategy);
SymbolMap references = (SymbolMap)FrameUtil.findJoinSourceNode(node.getFirstChild()).getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
ntjStrategy.setLeftMap(references);
references = (SymbolMap)FrameUtil.findJoinSourceNode(node.getLastChild()).getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
ntjStrategy.setRightMap(references);
} else {
NestedLoopJoinStrategy nljStrategy = new NestedLoopJoinStrategy();
jnode.setJoinStrategy(nljStrategy);
}
Criteria joinCrit = Criteria.combineCriteria(joinCrits);
jnode.setJoinCriteria(joinCrit);
processNode = jnode;
jnode.setDependentValueSource(depValueSource);
break;
case NodeConstants.Types.ACCESS:
ProcessorPlan plan = (ProcessorPlan) node.getProperty(NodeConstants.Info.PROCESSOR_PLAN);
if(plan != null) {
PlanExecutionNode peNode = null;
Criteria crit = (Criteria)node.getProperty(NodeConstants.Info.PROCEDURE_CRITERIA);
if (crit != null) {
List references = (List)node.getProperty(NodeConstants.Info.PROCEDURE_INPUTS);
List defaults = (List)node.getProperty(NodeConstants.Info.PROCEDURE_DEFAULTS);
peNode = new DependentProcedureExecutionNode(getID(), crit, references, defaults);
} else {
peNode = new PlanExecutionNode(getID());
}
peNode.setProcessorPlan(plan);
processNode = peNode;
} else {
AccessNode aNode = null;
Command command = (Command) node.getProperty(NodeConstants.Info.ATOMIC_REQUEST);
Object modelID = node.getProperty(NodeConstants.Info.MODEL_ID);
if(node.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
if (command instanceof StoredProcedure) {
List references = (List)node.getProperty(NodeConstants.Info.PROCEDURE_INPUTS);
List defaults = (List)node.getProperty(NodeConstants.Info.PROCEDURE_DEFAULTS);
Criteria crit = (Criteria)node.getProperty(NodeConstants.Info.PROCEDURE_CRITERIA);
DependentProcedureAccessNode depAccessNode = new DependentProcedureAccessNode(getID(), crit, references, defaults);
processNode = depAccessNode;
aNode = depAccessNode;
} else {
//create dependent access node
DependentAccessNode depAccessNode = new DependentAccessNode(getID());
if(modelID != null){
depAccessNode.setMaxSetSize(CapabilitiesUtil.getMaxInCriteriaSize(modelID, metadata, capFinder));
depAccessNode.setMaxPredicates(CapabilitiesUtil.getMaxDependentPredicates(modelID, metadata, capFinder));
}
processNode = depAccessNode;
aNode = depAccessNode;
}
aNode.setShouldEvaluateExpressions(true);
} else {
// create access node
aNode = new AccessNode(getID());
processNode = aNode;
//-- special handling for temp tables. currently they cannot perform projection
try {
if (command instanceof Query) {
processNode = correctProjectionInternalTables(node, aNode);
}
} catch (QueryMetadataException err) {
throw new TeiidComponentException(err);
}
aNode.setShouldEvaluateExpressions(EvaluatableVisitor.needsProcessingEvaluation(command));
}
if (command instanceof QueryCommand) {
try {
command = (Command)command.clone();
boolean aliasGroups = modelID != null && CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder);
boolean aliasColumns = modelID != null && CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder);
command.acceptVisitor(new AliasGenerator(aliasGroups, !aliasColumns));
} catch (QueryMetadataException err) {
throw new TeiidComponentException(err);
}
}
aNode.setCommand(command);
aNode.setModelName(getRoutingName(node));
}
break;
case NodeConstants.Types.SELECT:
Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
SelectNode selnode = new SelectNode(getID());
selnode.setCriteria(crit);
processNode = selnode;
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);
}
} else {
JoinNode joinAsSet = new JoinNode(getID());
joinAsSet.setJoinStrategy(new MergeJoinStrategy(SortOption.SORT_DISTINCT, SortOption.SORT_DISTINCT, true));