Search in sources :

Example 1 with PreOrPostOrderNavigator

use of org.teiid.query.sql.navigator.PreOrPostOrderNavigator in project teiid by teiid.

the class ExpressionMappingVisitor method mapExpressions.

/**
 * The object is modified in place, so is not returned.
 * @param obj Language object
 * @param exprMap Expression map, Expression to Expression
 */
public static void mapExpressions(LanguageObject obj, Map<? extends Expression, ? extends Expression> exprMap, boolean deep) {
    if (obj == null || exprMap == null || exprMap.isEmpty()) {
        return;
    }
    final ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(exprMap);
    visitor.elementSymbolsOnly = true;
    boolean preOrder = true;
    boolean useReverseMapping = true;
    for (Map.Entry<? extends Expression, ? extends Expression> entry : exprMap.entrySet()) {
        if (!(entry.getKey() instanceof ElementSymbol)) {
            visitor.elementSymbolsOnly = false;
            break;
        }
    }
    if (!visitor.elementSymbolsOnly) {
        for (Map.Entry<? extends Expression, ? extends Expression> entry : exprMap.entrySet()) {
            if (!(entry.getValue() instanceof ElementSymbol)) {
                useReverseMapping = !Collections.disjoint(GroupsUsedByElementsVisitor.getGroups(exprMap.keySet()), GroupsUsedByElementsVisitor.getGroups(exprMap.values()));
                break;
            }
        }
    } else {
        preOrder = false;
        useReverseMapping = false;
    }
    if (useReverseMapping) {
        final Set<Expression> reverseSet = new HashSet<Expression>(exprMap.values());
        PreOrPostOrderNavigator pon = new PreOrPostOrderNavigator(visitor, PreOrPostOrderNavigator.PRE_ORDER, deep) {

            @Override
            protected void visitNode(LanguageObject obj) {
                if (!(obj instanceof Expression) || !reverseSet.contains(obj)) {
                    super.visitNode(obj);
                }
            }
        };
        obj.acceptVisitor(pon);
    } else {
        PreOrPostOrderNavigator.doVisit(obj, visitor, preOrder, deep);
    }
}
Also used : ExceptionExpression(org.teiid.query.sql.proc.ExceptionExpression) PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator) Map(java.util.Map) LanguageObject(org.teiid.query.sql.LanguageObject) HashSet(java.util.HashSet)

Example 2 with PreOrPostOrderNavigator

use of org.teiid.query.sql.navigator.PreOrPostOrderNavigator in project teiid by teiid.

the class CorrelatedReferenceCollectorVisitor method collectReferences.

/**
 * <p>Helper to use this visitor.</p>
 * @param obj The Language object that is to be visited
 * @param groupSymbols Collection of GroupSymbols to restrict collection to - these are the groups
 * that the client (outer query) is interested in references to from the correlated subquery
 * @param correlatedReferences List of References collected
 */
public static final void collectReferences(final LanguageObject obj, final Collection<GroupSymbol> groupSymbols, List<Reference> correlatedReferences, QueryMetadataInterface metadata) {
    final Set<GroupSymbol> groups = new HashSet<GroupSymbol>(groupSymbols);
    final CorrelatedReferenceCollectorVisitor visitor = new CorrelatedReferenceCollectorVisitor(groups, correlatedReferences);
    visitor.metadata = metadata;
    visitor.queryRoot = obj instanceof Command;
    obj.acceptVisitor(new PreOrPostOrderNavigator(visitor, PreOrPostOrderNavigator.PRE_ORDER, true) {

        @Override
        public void visit(Query query) {
            // don't allow confusion with deep nesting by removing intermediate groups
            List<GroupSymbol> fromGroups = null;
            if (query.getFrom() != null) {
                fromGroups = query.getFrom().getGroups();
                HashMap<GroupSymbol, GroupSymbol> groupMap = new HashMap<GroupSymbol, GroupSymbol>();
                for (GroupSymbol g : fromGroups) {
                    groupMap.put(g, g);
                }
                visitor.outerGroups.add(groupMap);
            }
            super.visit(query);
            if (fromGroups != null) {
                visitor.outerGroups.remove(visitor.outerGroups.size() - 1);
            }
        }
    });
}
Also used : Query(org.teiid.query.sql.lang.Query) Command(org.teiid.query.sql.lang.Command) HashMap(java.util.HashMap) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 3 with PreOrPostOrderNavigator

use of org.teiid.query.sql.navigator.PreOrPostOrderNavigator in project teiid by teiid.

the class MultiSourceElementReplacementVisitor method visit.

public static void visit(String bindingName, QueryMetadataInterface metadata, Command processingCommand) {
    MultiSourceElementReplacementVisitor visitor = new MultiSourceElementReplacementVisitor(bindingName, metadata);
    PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, PreOrPostOrderNavigator.PRE_ORDER, true);
    nav.setSkipEvaluatable(true);
    processingCommand.acceptVisitor(nav);
}
Also used : PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator)

Example 4 with PreOrPostOrderNavigator

use of org.teiid.query.sql.navigator.PreOrPostOrderNavigator in project teiid by teiid.

the class RelationalPlanner method replaceSymbol.

private void replaceSymbol(final QueryCommand command, final GroupSymbol old, final GroupSymbol gs) {
    PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(new LanguageVisitor() {

        @Override
        public void visit(UnaryFromClause obj) {
            if (old.getMetadataID() == obj.getGroup().getMetadataID()) {
                String def = obj.getGroup().getDefinition();
                if (def != null) {
                    String name = obj.getGroup().getName();
                    obj.setGroup(gs.clone());
                    obj.getGroup().setDefinition(gs.getName());
                    obj.getGroup().setName(name);
                } else {
                    obj.setGroup(gs);
                }
            }
        }

        @Override
        public void visit(ElementSymbol es) {
            if (es.getGroupSymbol().getMetadataID() == old.getMetadataID()) {
                String def = es.getGroupSymbol().getDefinition();
                if (def != null) {
                    String name = es.getGroupSymbol().getName();
                    es.setGroupSymbol(gs.clone());
                    es.getGroupSymbol().setDefinition(gs.getName());
                    es.getGroupSymbol().setName(name);
                } else {
                    es.setGroupSymbol(gs);
                }
            }
        }

        @Override
        public void visit(Reference obj) {
            if (obj.getExpression() != null) {
                visit(obj.getExpression());
            }
        }
    }, PreOrPostOrderNavigator.PRE_ORDER, true) {

        /**
         * Add to the navigation the visitation of expanded commands
         * which are inlined with clauses
         */
        @Override
        public void visit(UnaryFromClause obj) {
            super.visit(obj);
            if (obj.getExpandedCommand() != null && !obj.getGroup().isProcedure()) {
                obj.getExpandedCommand().acceptVisitor(this);
            }
        }
    };
    command.acceptVisitor(nav);
}
Also used : LanguageVisitor(org.teiid.query.sql.LanguageVisitor) PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator)

Example 5 with PreOrPostOrderNavigator

use of org.teiid.query.sql.navigator.PreOrPostOrderNavigator in project teiid by teiid.

the class CriteriaCapabilityValidatorVisitor method canPushLanguageObject.

public static boolean canPushLanguageObject(LanguageObject obj, Object modelID, final QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, boolean isJoin, boolean isSelectClause, final boolean multiValuedReferences) throws QueryMetadataException, TeiidComponentException {
    if (obj == null) {
        return true;
    }
    if (modelID == null || metadata.isVirtualModel(modelID)) {
        // Couldn't determine model ID, so give up
        return false;
    }
    String modelName = metadata.getFullName(modelID);
    SourceCapabilities caps = capFinder.findCapabilities(modelName);
    if (caps == null) {
        // this doesn't seem right, but tests were expecting it...
        return true;
    }
    CriteriaCapabilityValidatorVisitor visitor = new CriteriaCapabilityValidatorVisitor(modelID, metadata, capFinder, caps);
    visitor.setCheckEvaluation(!multiValuedReferences);
    visitor.analysisRecord = analysisRecord;
    visitor.isJoin = isJoin;
    visitor.isSelectClause = isSelectClause;
    // we use an array to represent multiple comparision attributes,
    // but we don't want that to inhibit pushdown as we'll account for that later
    // in criteria processing
    final EvaluatableVisitor ev = new EvaluatableVisitor(modelID, metadata, capFinder);
    PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, PreOrPostOrderNavigator.POST_ORDER, false) {

        @Override
        public void visit(DependentSetCriteria obj1) {
            if (obj1.hasMultipleAttributes()) {
                Array array = (Array) obj1.getExpression();
                visitNodes(array.getExpressions());
                super.postVisitVisitor(obj1);
            } else {
                super.visit(obj1);
            }
        }

        @Override
        protected void visitNode(LanguageObject obj) {
            if (obj == null) {
                return;
            }
            Determinism d = ev.getDeterminismLevel();
            boolean pushDown = ev.requiresEvaluation(EvaluationLevel.PUSH_DOWN);
            // decend with clean state, then restore
            ev.reset();
            super.visitNode(obj);
            ev.setDeterminismLevel(d);
            if (pushDown) {
                ev.evaluationNotPossible(EvaluationLevel.PUSH_DOWN);
            }
        }

        @Override
        protected void visitVisitor(LanguageObject obj) {
            if (obj == null) {
                return;
            }
            if (!ev.requiresEvaluation(EvaluationLevel.PUSH_DOWN) && ev.getDeterminismLevel() != Determinism.NONDETERMINISTIC) {
                if (obj instanceof ElementSymbol) {
                    ElementSymbol es = (ElementSymbol) obj;
                    if (es.getMetadataID() != null) {
                        try {
                            if (metadata.isMultiSourceElement(es.getMetadataID())) {
                                // no need to visit
                                return;
                            }
                        } catch (QueryMetadataException e) {
                        } catch (TeiidComponentException e) {
                        }
                    }
                }
                obj.acceptVisitor(ev);
                if (!multiValuedReferences && obj instanceof Expression) {
                    if (obj instanceof Function) {
                        if (!(obj instanceof AggregateSymbol)) {
                            Function f = (Function) obj;
                            if (f.getFunctionDescriptor().getPushdown() != PushDown.MUST_PUSHDOWN && f.getFunctionDescriptor().getDeterministic() != Determinism.NONDETERMINISTIC) {
                                // don't need to consider
                                return;
                            }
                        }
                    } else if (obj instanceof Criteria && !(obj instanceof SubqueryContainer) && !(obj instanceof DependentSetCriteria)) {
                        // don't need to consider
                        return;
                    }
                }
            }
            super.visitVisitor(obj);
        }
    };
    obj.acceptVisitor(nav);
    if (visitor.getException() != null) {
        throw visitor.getException();
    }
    return visitor.isValid();
}
Also used : Determinism(org.teiid.metadata.FunctionMethod.Determinism) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) EvaluatableVisitor(org.teiid.query.sql.visitor.EvaluatableVisitor) PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator) TeiidComponentException(org.teiid.core.TeiidComponentException) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities) LanguageObject(org.teiid.query.sql.LanguageObject)

Aggregations

PreOrPostOrderNavigator (org.teiid.query.sql.navigator.PreOrPostOrderNavigator)6 HashSet (java.util.HashSet)2 LanguageObject (org.teiid.query.sql.LanguageObject)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)1 TeiidComponentException (org.teiid.core.TeiidComponentException)1 Determinism (org.teiid.metadata.FunctionMethod.Determinism)1 SourceCapabilities (org.teiid.query.optimizer.capabilities.SourceCapabilities)1 LanguageVisitor (org.teiid.query.sql.LanguageVisitor)1 Command (org.teiid.query.sql.lang.Command)1 Query (org.teiid.query.sql.lang.Query)1 ExceptionExpression (org.teiid.query.sql.proc.ExceptionExpression)1 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)1 EvaluatableVisitor (org.teiid.query.sql.visitor.EvaluatableVisitor)1