List<WithQueryCommand> withList = null;
Object modelID = null;
boolean supportsWithPushdown = true;
List<WithQueryCommand> pushDownWith = null;
if (command instanceof QueryCommand) {
QueryCommand queryCommand = (QueryCommand)command;
final HashSet<String> names = new HashSet<String>();
if (queryCommand.getWith() != null) {
withList = queryCommand.getWith();
for (WithQueryCommand with : queryCommand.getWith()) {
Command subCommand = with.getCommand();
ProcessorPlan procPlan = QueryOptimizer.optimizePlan(subCommand, metadata, idGenerator, capFinder, analysisRecord, context);
subCommand.setProcessorPlan(procPlan);
QueryCommand withCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(procPlan);
if (withCommand != null && supportsWithPushdown) {
modelID = CriteriaCapabilityValidatorVisitor.validateCommandPushdown(modelID, metadata, capFinder, withCommand);
}
if (modelID == null) {
supportsWithPushdown = false;
} else {
if (pushDownWith == null) {
pushDownWith = new ArrayList<WithQueryCommand>();
}
WithQueryCommand wqc = new WithQueryCommand(with.getGroupSymbol(), with.getColumns(), withCommand);
pushDownWith.add(wqc);
}
names.add(with.getGroupSymbol().getCanonicalName());
}
if (modelID != null && supportsWithPushdown) {
supportsWithPushdown = CapabilitiesUtil.supports(Capability.COMMON_TABLE_EXPRESSIONS, modelID, metadata, capFinder);
}
if (supportsWithPushdown) {
addModelIds(command, modelID, names);
}
}
}
PlanNode plan;
try {
plan = generatePlan(command);
} catch (TeiidProcessingException e) {
throw new QueryPlannerException(e, e.getMessage());
}
if(debug) {
analysisRecord.println("\nCANONICAL PLAN: \n" + plan); //$NON-NLS-1$
}
// Connect ProcessorPlan to SubqueryContainer (if any) of SELECT or PROJECT nodes
connectSubqueryContainers(plan); //TODO: merge with node creation
// Set top column information on top node
List<SingleElementSymbol> topCols = Util.deepClone(command.getProjectedSymbols(), SingleElementSymbol.class);
// Build rule set based on hints
RuleStack rules = buildRules();
// Run rule-based optimizer
plan = executeRules(rules, plan);
RelationalPlan result = planToProcessConverter.convert(plan);
if (withList != null && supportsWithPushdown) {
QueryCommand queryCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(result);
if (queryCommand != null) {
if (CriteriaCapabilityValidatorVisitor.validateCommandPushdown(modelID, metadata, capFinder, queryCommand) == null) {
supportsWithPushdown = false;
} else {
queryCommand.setWith(pushDownWith);
}
} else {
supportsWithPushdown = false;
}
}