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);
}
}
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);
}
}
});
}
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);
}
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);
}
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();
}
Aggregations