use of org.teiid.query.optimizer.relational.rules.RuleMergeCriteria in project teiid by teiid.
the class QueryRewriter method rewriteQuery.
private Command rewriteQuery(Query query) throws TeiidComponentException, TeiidProcessingException {
// Rewrite from clause
From from = query.getFrom();
if (from != null) {
List<FromClause> clauses = new ArrayList<FromClause>(from.getClauses().size());
Iterator<FromClause> clauseIter = from.getClauses().iterator();
while (clauseIter.hasNext()) {
clauses.add(rewriteFromClause(query, clauseIter.next()));
}
from.setClauses(clauses);
} else {
query.setOrderBy(null);
}
// Rewrite criteria
Criteria crit = query.getCriteria();
if (crit != null) {
boolean preserveUnknownOld = preserveUnknown;
preserveUnknown = false;
Criteria clone = null;
if (processing && query.getGroupBy() == null && query.hasAggregates()) {
clone = (Criteria) crit.clone();
}
crit = rewriteCriteria(crit);
preserveUnknown = preserveUnknownOld;
if (crit.equals(TRUE_CRITERIA)) {
query.setCriteria(null);
} else if (crit.equals(UNKNOWN_CRITERIA)) {
query.setCriteria(FALSE_CRITERIA);
} else {
query.setCriteria(crit);
}
// aggregates and an always false predicate
if (clone != null && query.getCriteria() != null && query.getCriteria().equals(FALSE_CRITERIA)) {
List<Criteria> crits = new ArrayList<Criteria>();
List<Criteria> parts = Criteria.separateCriteriaByAnd(clone);
if (parts.size() > 1) {
for (Criteria c : parts) {
crits.add(rewriteCriteria(c));
}
query.setCriteria(new CompoundCriteria(parts));
}
}
}
if (from != null) {
rewriteSubqueriesAsJoins(query);
}
query = rewriteGroupBy(query);
// Rewrite having
Criteria having = query.getHaving();
if (having != null) {
boolean preserveUnknownOld = preserveUnknown;
preserveUnknown = false;
crit = rewriteCriteria(having);
preserveUnknown = preserveUnknownOld;
if (crit == TRUE_CRITERIA) {
query.setHaving(null);
} else {
query.setHaving(crit);
}
}
// remove multiple element symbols
boolean hasMes = false;
for (Expression ex : query.getSelect().getSymbols()) {
if (ex instanceof MultipleElementSymbol) {
hasMes = true;
}
}
if (hasMes) {
query.getSelect().setSymbols(query.getSelect().getProjectedSymbols());
}
boolean preserveUnknownOld = preserveUnknown;
preserveUnknown = true;
rewriteExpressions(query.getSelect());
if (from != null) {
List<Expression> symbols = query.getSelect().getSymbols();
RuleMergeCriteria rmc = new RuleMergeCriteria(null, null, null, this.context, this.metadata);
TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
List<GroupSymbol> groups = query.getFrom().getGroups();
for (GroupSymbol gs : groups) {
names.add(gs.getName());
}
PlannedResult plannedResult = new PlannedResult();
for (int i = 0; i < symbols.size(); i++) {
Expression symbol = symbols.get(i);
plannedResult.reset();
rmc.findSubquery(SymbolMap.getExpression(symbol), context != null ? context.getOptions().isSubqueryUnnestDefault() : false, plannedResult);
if (plannedResult.query == null || plannedResult.query.getProcessorPlan() != null || plannedResult.query.getFrom() == null) {
continue;
}
determineCorrelatedReferences(groups, plannedResult);
boolean requiresDistinct = requiresDistinctRows(query);
if (!rmc.planQuery(groups, requiresDistinct, plannedResult)) {
continue;
}
Query q = convertToJoin(plannedResult, names, query, true);
symbols.set(i, new AliasSymbol(ExpressionSymbol.getName(symbol), (Expression) q.getProjectedSymbols().get(0).clone()));
}
}
query = (Query) rewriteOrderBy(query);
preserveUnknown = preserveUnknownOld;
if (query.getLimit() != null) {
query.setLimit(rewriteLimitClause(query.getLimit()));
}
if (query.getInto() != null) {
return rewriteSelectInto(query);
}
return query;
}
use of org.teiid.query.optimizer.relational.rules.RuleMergeCriteria in project teiid by teiid.
the class QueryRewriter method rewriteSubqueriesAsJoins.
private void rewriteSubqueriesAsJoins(Query query) 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();
TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (GroupSymbol gs : groups) {
names.add(gs.getName());
}
for (Iterator<Criteria> crits = current.iterator(); crits.hasNext(); ) {
PlannedResult plannedResult = rmc.findSubquery(crits.next(), context != null ? context.getOptions().isSubqueryUnnestDefault() : false);
if (plannedResult.not || plannedResult.query == null || plannedResult.query.getProcessorPlan() != null || plannedResult.query.getWith() != null) {
continue;
}
determineCorrelatedReferences(groups, plannedResult);
boolean requiresDistinct = requiresDistinctRows(query);
if (!rmc.planQuery(groups, requiresDistinct, plannedResult)) {
continue;
}
crits.remove();
convertToJoin(plannedResult, names, query, false);
// transform the query into an inner join
}
query.setCriteria(Criteria.combineCriteria(query.getCriteria(), Criteria.combineCriteria(current)));
}
Aggregations