Search in sources :

Example 1 with PlannedResult

use of org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult 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;
}
Also used : RuleMergeCriteria(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria) RuleMergeCriteria(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria) PlannedResult(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult)

Example 2 with PlannedResult

use of org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult 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)));
}
Also used : RuleMergeCriteria(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria) RuleMergeCriteria(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria) PlannedResult(org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult)

Aggregations

RuleMergeCriteria (org.teiid.query.optimizer.relational.rules.RuleMergeCriteria)2 PlannedResult (org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult)2