throws TeiidComponentException, QueryMetadataException,
QueryResolverException {
if (query.getCriteria() == null) {
return;
}
RuleMergeCriteria rmc = new RuleMergeCriteria(null, null, null, this.context, this.metadata);
List<Criteria> current = Criteria.separateCriteriaByAnd(query.getCriteria());
query.setCriteria(null);
List<GroupSymbol> groups = query.getFrom().getGroups();
HashSet<String> names = new HashSet<String>();
for (GroupSymbol gs : groups) {
names.add(gs.getCanonicalName());
}
for (Iterator<Criteria> crits = current.iterator(); crits.hasNext();) {
PlannedResult plannedResult = rmc.findSubquery(crits.next());
if (plannedResult.not || plannedResult.query == null || plannedResult.query.getProcessorPlan() != null
|| plannedResult.query.getWith() != null) {
continue;
}
if (plannedResult.query.getCorrelatedReferences() == null) {
//create the correlated refs if they exist
//there is a little bit of a design problem here that null usually means no refs.
ArrayList<Reference> correlatedReferences = new ArrayList<Reference>();
CorrelatedReferenceCollectorVisitor.collectReferences(plannedResult.query, groups, correlatedReferences);
if (!correlatedReferences.isEmpty()) {
SymbolMap map = new SymbolMap();
for (Reference reference : correlatedReferences) {
map.addMapping(reference.getExpression(), reference.getExpression());
}
plannedResult.query.setCorrelatedReferences(map);
}
}
boolean requiresDistinct = requiresDistinctRows(query);
if (!rmc.planQuery(groups, requiresDistinct, plannedResult)) {
continue;
}
if (requiresDistinct) {
//check for key preservation
HashSet<GroupSymbol> keyPreservingGroups = new HashSet<GroupSymbol>();