Search in sources :

Example 1 with SupportedJoinCriteria

use of org.teiid.translator.ExecutionFactory.SupportedJoinCriteria in project teiid by teiid.

the class RulePlanJoins method groupAcrossLeftOuter.

private void groupAcrossLeftOuter(QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, CommandContext context, JoinRegion joinRegion) throws QueryMetadataException, TeiidComponentException, AssertionError {
    if (joinRegion.getLeft() == null || joinRegion.getJoinRoot().getLastChild().getType() != NodeConstants.Types.ACCESS || joinRegion.getJoinRoot().getFirstChild().getType() == NodeConstants.Types.ACCESS) {
        return;
    }
    PlanNode planNodeRight = joinRegion.getJoinRoot().getLastChild();
    Object modelId = RuleRaiseAccess.getModelIDFromAccess(planNodeRight, metadata);
    Map<Object, List<PlanNode>> accessMapLeft = getAccessMap(metadata, capabilitiesFinder, joinRegion.getLeft());
    // TODO: what about same connector, but not the same model
    List<PlanNode> joinSourcesLeft = accessMapLeft.get(modelId);
    if (joinSourcesLeft == null) {
        return;
    }
    SupportedJoinCriteria sjc = CapabilitiesUtil.getSupportedJoinCriteria(modelId, metadata, capabilitiesFinder);
    Set<GroupSymbol> groups = new HashSet<GroupSymbol>();
    List<Criteria> joinCriteria = (List<Criteria>) joinRegion.getJoinRoot().getProperty(Info.JOIN_CRITERIA);
    for (Criteria crit : joinCriteria) {
        if (!RuleRaiseAccess.isSupportedJoinCriteria(sjc, crit, modelId, metadata, capabilitiesFinder, null)) {
            return;
        }
    }
    GroupsUsedByElementsVisitor.getGroups(joinCriteria, groups);
    groups.removeAll(planNodeRight.getGroups());
    for (PlanNode planNode : joinSourcesLeft) {
        if (!planNode.getGroups().containsAll(groups)) {
            continue;
        }
        // see if we can group the planNode with the other side
        if (RuleRaiseAccess.canRaiseOverJoin(Arrays.asList(planNode, planNodeRight), metadata, capabilitiesFinder, joinCriteria, JoinType.JOIN_LEFT_OUTER, null, context, false, false) == null) {
            continue;
        }
        // remove the parent loj, create a new loj
        joinRegion.getLeft().getJoinSourceNodes().remove(planNode);
        PlanNode joinNode = createJoinNode(planNode, planNodeRight, joinCriteria, JoinType.JOIN_LEFT_OUTER);
        PlanNode newAccess = RuleRaiseAccess.raiseAccessOverJoin(joinNode, joinNode.getFirstChild(), modelId, capabilitiesFinder, metadata, false);
        for (Set<PlanNode> source : joinRegion.getLeft().getCritieriaToSourceMap().values()) {
            if (source.remove(planNode)) {
                source.add(newAccess);
            }
        }
        joinRegion.getLeft().getJoinSourceNodes().put(newAccess, newAccess);
        PlanNode root = joinRegion.getJoinRoot();
        root.getParent().replaceChild(root, root.getFirstChild());
        joinRegion.getLeft().reconstructJoinRegoin();
        break;
    }
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria)

Example 2 with SupportedJoinCriteria

use of org.teiid.translator.ExecutionFactory.SupportedJoinCriteria in project teiid by teiid.

the class RuleRaiseAccess method canRaiseOverJoin.

static Object canRaiseOverJoin(List<PlanNode> children, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, List<Criteria> crits, JoinType type, AnalysisRecord record, CommandContext context, boolean considerOptional, boolean considerLateral) throws QueryMetadataException, TeiidComponentException {
    // we only want to consider binary joins
    if (children.size() != 2) {
        return null;
    }
    Object modelID = null;
    boolean multiSource = false;
    Set<Object> groupIDs = new HashSet<Object>();
    int groupCount = 0;
    LinkedList<CompareCriteria> thetaCriteria = new LinkedList<CompareCriteria>();
    SupportedJoinCriteria sjc = null;
    for (PlanNode childNode : children) {
        boolean lateral = false;
        boolean procedure = false;
        if (considerLateral && childNode.getType() == NodeConstants.Types.SOURCE && childNode.getFirstChild() != null && childNode.getProperty(Info.CORRELATED_REFERENCES) != null) {
            if (FrameUtil.getNestedPlan(childNode.getFirstChild()) != null) {
                return null;
            }
            Command command = FrameUtil.getNonQueryCommand(childNode.getFirstChild());
            if (command instanceof StoredProcedure) {
                procedure = true;
                if (!CapabilitiesUtil.supports(Capability.QUERY_FROM_PROCEDURE_TABLE, modelID, metadata, capFinder)) {
                    return null;
                }
                // this should look like source/project/access - if not, then back out
                if (childNode.getFirstChild().getType() == NodeConstants.Types.PROJECT) {
                    childNode = childNode.getFirstChild();
                }
            }
            if (childNode.getFirstChild().getType() == NodeConstants.Types.ACCESS) {
                childNode = childNode.getFirstChild();
            } else {
                return null;
            }
            lateral = true;
        }
        if (childNode.getType() != NodeConstants.Types.ACCESS) {
            return null;
        }
        if (childNode.hasCollectionProperty(NodeConstants.Info.ACCESS_PATTERNS)) {
            // $NON-NLS-1$ //$NON-NLS-2$
            childNode.recordDebugAnnotation("access pattern not satisfied by join", modelID, "not pushing parent join", record, metadata);
            return null;
        }
        Object accessModelID = getModelIDFromAccess(childNode, metadata);
        if (accessModelID == null) {
            return null;
        }
        groupCount += childNode.getGroups().size();
        // Add all group metadata IDs to the list but check before each to make
        // sure group hasn't already been seen - if so, bail out - this is a self join
        // Unless model supports self joins, in which case, don't bail out.
        boolean supportsSelfJoins = CapabilitiesUtil.supportsSelfJoins(accessModelID, metadata, capFinder);
        if (!supportsSelfJoins) {
            for (GroupSymbol groupSymbol : childNode.getGroups()) {
                Object groupID = groupSymbol.getMetadataID();
                if (!groupIDs.add(groupID)) {
                    // Already seen group - can't raise access over self join
                    return null;
                }
            }
        }
        // check the join criteria now that we know the model
        if (modelID == null) {
            if (!CapabilitiesUtil.supportsJoin(accessModelID, type, metadata, capFinder)) {
                return null;
            }
            sjc = CapabilitiesUtil.getSupportedJoinCriteria(accessModelID, metadata, capFinder);
            // see if we can emulate the inner join using an outer
            if (!type.isOuter() && !CapabilitiesUtil.supports(Capability.QUERY_FROM_JOIN_INNER, accessModelID, metadata, capFinder) && (crits != null) && !crits.isEmpty()) {
                // TODO: the IS NOT NULL check is not strictly needed as we could check predicates to see if we are already null filtering
                if (!CapabilitiesUtil.supports(Capability.CRITERIA_ISNULL, accessModelID, metadata, capFinder) || !CapabilitiesUtil.supports(Capability.CRITERIA_NOT, accessModelID, metadata, capFinder)) {
                    return null;
                }
                if (sjc == SupportedJoinCriteria.ANY) {
                    // quick check to see if we can find an element to be nullable
                    boolean valid = false;
                    for (Criteria crit : crits) {
                        if (!(crit instanceof CompareCriteria)) {
                            continue;
                        }
                        CompareCriteria cc = (CompareCriteria) crit;
                        if ((cc.getLeftExpression() instanceof ElementSymbol) || (cc.getRightExpression() instanceof ElementSymbol)) {
                            valid = true;
                        }
                    }
                    if (!valid) {
                        // TODO: check if any of the already pushed predicates can satisfy
                        return null;
                    }
                }
            }
            if (crits != null && !crits.isEmpty()) {
                for (Criteria crit : crits) {
                    if (!isSupportedJoinCriteria(sjc, crit, accessModelID, metadata, capFinder, record)) {
                        if (crit instanceof CompareCriteria) {
                            CompareCriteria cc = (CompareCriteria) crit;
                            if (cc.isOptional()) {
                                cc.setOptional(true);
                                continue;
                            }
                        }
                        // TODO: plan based upon a predicate subset when possible
                        return null;
                    } else if (crit instanceof CompareCriteria) {
                        thetaCriteria.add((CompareCriteria) crit);
                    }
                }
                if (sjc == SupportedJoinCriteria.KEY) {
                    PlanNode left = children.get(0);
                    PlanNode right = children.get(1);
                    if (left.getGroups().size() != 1) {
                        if (right.getGroups().size() != 1) {
                            // require the simple case of 1 side being a single group
                            return null;
                        }
                        if (type != JoinType.JOIN_INNER) {
                            return null;
                        }
                        left = children.get(1);
                        right = children.get(0);
                    }
                    LinkedList<Expression> leftExpressions = new LinkedList<Expression>();
                    LinkedList<Expression> rightExpressions = new LinkedList<Expression>();
                    RuleChooseJoinStrategy.separateCriteria(left.getGroups(), right.getGroups(), leftExpressions, rightExpressions, crits, new LinkedList<Criteria>());
                    ArrayList<Object> leftIds = new ArrayList<Object>(leftExpressions.size());
                    ArrayList<Object> rightIds = new ArrayList<Object>(rightExpressions.size());
                    for (Expression expr : leftExpressions) {
                        if (expr instanceof ElementSymbol) {
                            leftIds.add(((ElementSymbol) expr).getMetadataID());
                        }
                    }
                    GroupSymbol rightGroup = null;
                    for (Expression expr : rightExpressions) {
                        if (expr instanceof ElementSymbol) {
                            ElementSymbol es = (ElementSymbol) expr;
                            if (rightGroup == null) {
                                rightGroup = es.getGroupSymbol();
                            } else if (!rightGroup.equals(es.getGroupSymbol())) {
                                return null;
                            }
                            rightIds.add(es.getMetadataID());
                        }
                    }
                    if (rightGroup == null) {
                        return null;
                    }
                    if (!matchesForeignKey(metadata, leftIds, rightIds, left.getGroups().iterator().next(), true, !type.isOuter() || type == JoinType.JOIN_LEFT_OUTER) && !matchesForeignKey(metadata, rightIds, leftIds, rightGroup, true, !type.isOuter())) {
                        return null;
                    }
                }
            }
            if (sjc != SupportedJoinCriteria.ANY && thetaCriteria.isEmpty()) {
                // cross join not supported
                return null;
            }
            if (type == JoinType.JOIN_LEFT_OUTER && !CapabilitiesUtil.supports(Capability.CRITERIA_ON_SUBQUERY, accessModelID, metadata, capFinder)) {
                PlanNode right = children.get(1);
                for (PlanNode node : NodeEditor.findAllNodes(right, NodeConstants.Types.SELECT, NodeConstants.Types.SOURCE)) {
                    for (SubqueryContainer<?> subqueryContainer : ValueIteratorProviderCollectorVisitor.getValueIteratorProviders((Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA))) {
                        if (!(subqueryContainer instanceof Evaluatable) || subqueryContainer.getCommand().getCorrelatedReferences() != null) {
                            return null;
                        }
                    }
                }
            }
            modelID = accessModelID;
            multiSource = childNode.hasBooleanProperty(Info.IS_MULTI_SOURCE);
        } else if (!CapabilitiesUtil.isSameConnector(modelID, accessModelID, metadata, capFinder) && !isConformed(metadata, capFinder, (Set<Object>) childNode.getProperty(Info.CONFORMED_SOURCES), modelID, (Set<Object>) children.get(0).getProperty(Info.CONFORMED_SOURCES), accessModelID)) {
            return null;
        } else if ((multiSource || childNode.hasBooleanProperty(Info.IS_MULTI_SOURCE)) && !context.getOptions().isImplicitMultiSourceJoin()) {
            // only allow raise if partitioned
            boolean multiSourceOther = childNode.hasBooleanProperty(Info.IS_MULTI_SOURCE);
            if (multiSource && multiSourceOther && (type == JoinType.JOIN_ANTI_SEMI || type == JoinType.JOIN_CROSS)) {
                return null;
            }
            ArrayList<Expression> leftExpressions = new ArrayList<Expression>();
            ArrayList<Expression> rightExpressions = new ArrayList<Expression>();
            RuleChooseJoinStrategy.separateCriteria(children.get(0).getGroups(), children.get(1).getGroups(), leftExpressions, rightExpressions, crits, new LinkedList<Criteria>());
            boolean needsOtherCrit = sjc != SupportedJoinCriteria.ANY;
            boolean partitioned = !multiSource || !multiSourceOther;
            for (int i = 0; i < leftExpressions.size() && (!partitioned || needsOtherCrit); i++) {
                boolean multi = isMultiSourceColumn(metadata, leftExpressions.get(i), children.get(0)) && isMultiSourceColumn(metadata, rightExpressions.get(i), children.get(1));
                if (multi) {
                    partitioned = true;
                } else {
                    needsOtherCrit = false;
                }
            }
            if (needsOtherCrit || !partitioned) {
                return null;
            }
        }
        if (lateral) {
            if ((!CapabilitiesUtil.supports(Capability.QUERY_FROM_JOIN_LATERAL, modelID, metadata, capFinder) || (crits != null && !crits.isEmpty() && !CapabilitiesUtil.supports(Capability.QUERY_FROM_JOIN_LATERAL_CONDITION, accessModelID, metadata, capFinder)))) {
                return null;
            }
            if (!procedure && CapabilitiesUtil.supports(Capability.QUERY_ONLY_FROM_JOIN_LATERAL_PROCEDURE, accessModelID, metadata, capFinder)) {
                return null;
            }
        }
    }
    // end walking through join node's children
    int maxGroups = CapabilitiesUtil.getMaxFromGroups(modelID, metadata, capFinder);
    if (maxGroups != -1 && maxGroups < groupCount) {
        return null;
    }
    if (crits != null && !crits.isEmpty()) {
        if (considerOptional) {
            for (CompareCriteria criteria : thetaCriteria) {
                criteria.setOptional(false);
            }
        } else {
            boolean hasCriteria = false;
            for (CompareCriteria criteria : thetaCriteria) {
                if (criteria.getIsOptional() == null || !criteria.isOptional()) {
                    hasCriteria = true;
                    break;
                }
            }
            if (!hasCriteria) {
                return null;
            }
        }
    }
    return modelID;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) LinkedList(java.util.LinkedList) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) Evaluatable(org.teiid.query.sql.lang.SubqueryContainer.Evaluatable) HashSet(java.util.HashSet)

Example 3 with SupportedJoinCriteria

use of org.teiid.translator.ExecutionFactory.SupportedJoinCriteria in project teiid by teiid.

the class RulePlanJoins method groupJoinsForPushing.

/**
 * This is a heuristic that checks for joins that may be pushed so they can be removed
 * before considering the joins that must be evaluated in MetaMatrix.
 *
 * By running this, we eliminate the need for running RuleRaiseAccess during join ordering
 *
 * @param metadata
 * @param joinRegion
 * @throws QueryMetadataException
 * @throws TeiidComponentException
 * @throws QueryPlannerException
 */
private void groupJoinsForPushing(QueryMetadataInterface metadata, CapabilitiesFinder capFinder, JoinRegion joinRegion, CommandContext context) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
    // TODO: consider moving select criteria if it is preventing a join from being pushed down
    // TODO: make the criteria checks based upon a guess at selectivity
    Map accessMap = getAccessMap(metadata, capFinder, joinRegion);
    boolean structureChanged = false;
    // search for combinations of join sources that should be pushed down
    for (Iterator accessNodeIter = accessMap.entrySet().iterator(); accessNodeIter.hasNext(); ) {
        Map.Entry entry = (Map.Entry) accessNodeIter.next();
        List<PlanNode> accessNodes = (List) entry.getValue();
        if (accessNodes.size() < 2) {
            continue;
        }
        int secondPass = -1;
        for (int i = accessNodes.size() - 1; i >= 0; i--) {
            PlanNode accessNode1 = accessNodes.get(i);
            Object modelId = RuleRaiseAccess.getModelIDFromAccess(accessNode1, metadata);
            SupportedJoinCriteria sjc = CapabilitiesUtil.getSupportedJoinCriteria(modelId, metadata, capFinder);
            int discoveredJoin = -1;
            for (int k = (secondPass == -1 ? accessNodes.size() - 1 : secondPass); k >= 0; k--) {
                if (k == i) {
                    continue;
                }
                PlanNode accessNode2 = accessNodes.get(k);
                List<PlanNode> criteriaNodes = joinRegion.getCriteriaNodes();
                List<PlanNode> joinCriteriaNodes = new LinkedList<PlanNode>();
                /* hasJoinCriteria will be true if
                     *  1. there is criteria between accessNode1 and accessNode2 exclusively
                     *  2. there is criteria between some other source (not the same logical connector) and accessNode1 or accessNode2
                     *  
                     *  Ideally we should be a little smarter in case 2 
                     *    - pushing down a same source cross join can be done if we know that a dependent join will be performed 
                     */
                boolean hasJoinCriteria = false;
                LinkedList<Criteria> joinCriteria = new LinkedList<Criteria>();
                for (PlanNode critNode : criteriaNodes) {
                    Set<PlanNode> sources = joinRegion.getCritieriaToSourceMap().get(critNode);
                    if (sources == null) {
                        continue;
                    }
                    if (sources.contains(accessNode1)) {
                        if (sources.contains(accessNode2) && sources.size() == 2) {
                            Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
                            if (RuleRaiseAccess.isSupportedJoinCriteria(sjc, crit, modelId, metadata, capFinder, null)) {
                                joinCriteriaNodes.add(critNode);
                                joinCriteria.add(crit);
                            }
                        } else if (!accessNodes.containsAll(sources)) {
                            hasJoinCriteria = true;
                        }
                    } else if (sources.contains(accessNode2) && !accessNodes.containsAll(sources)) {
                        hasJoinCriteria = true;
                    }
                }
                /*
                     * If we failed to find direct criteria, a cross join may still be acceptable
                     */
                if (joinCriteriaNodes.isEmpty() && (hasJoinCriteria || !canPushCrossJoin(metadata, accessNode1, accessNode2))) {
                    continue;
                }
                List<PlanNode> toTest = Arrays.asList(accessNode1, accessNode2);
                JoinType joinType = joinCriteria.isEmpty() ? JoinType.JOIN_CROSS : JoinType.JOIN_INNER;
                /*
                     * We need to limit the heuristic grouping as we don't want to create larger source queries than necessary
                     */
                boolean shouldPush = true;
                int sourceCount = NodeEditor.findAllNodes(accessNode1, NodeConstants.Types.SOURCE, NodeConstants.Types.SOURCE).size();
                sourceCount += NodeEditor.findAllNodes(accessNode2, NodeConstants.Types.SOURCE, NodeConstants.Types.SOURCE).size();
                if (!context.getOptions().isAggressiveJoinGrouping() && accessMap.size() > 1 && joinType == JoinType.JOIN_INNER && (sourceCount > 2 && (accessNode1.hasProperty(Info.MAKE_DEP) || accessNode2.hasProperty(Info.MAKE_DEP)) || sourceCount > 3) && !canPushCrossJoin(metadata, accessNode1, accessNode2)) {
                    Collection<GroupSymbol> leftGroups = accessNode1.getGroups();
                    Collection<GroupSymbol> rightGroups = accessNode2.getGroups();
                    List<Expression> leftExpressions = new ArrayList<Expression>();
                    List<Expression> rightExpressions = new ArrayList<Expression>();
                    List<Criteria> nonEquiJoinCriteria = new ArrayList<Criteria>();
                    RuleChooseJoinStrategy.separateCriteria(leftGroups, rightGroups, leftExpressions, rightExpressions, joinCriteria, nonEquiJoinCriteria);
                    // allow a 1-1 join
                    if (!NewCalculateCostUtil.usesKey(accessNode1, leftExpressions, metadata) || !NewCalculateCostUtil.usesKey(accessNode2, rightExpressions, metadata)) {
                        // don't push heuristically
                        shouldPush = false;
                    }
                }
                // try to push to the source
                if (!shouldPush || RuleRaiseAccess.canRaiseOverJoin(toTest, metadata, capFinder, joinCriteria, joinType, null, context, secondPass != -1, false) == null) {
                    if (secondPass == -1 && sjc != SupportedJoinCriteria.KEY && discoveredJoin == -1) {
                        for (Criteria criteria : joinCriteria) {
                            if (criteria instanceof CompareCriteria && ((CompareCriteria) criteria).isOptional()) {
                                discoveredJoin = k;
                            }
                        }
                    }
                    continue;
                }
                secondPass = -1;
                discoveredJoin = -1;
                structureChanged = true;
                // remove the information that is no longer relevant to the join region
                joinRegion.getCritieriaToSourceMap().keySet().removeAll(joinCriteriaNodes);
                joinRegion.getCriteriaNodes().removeAll(joinCriteriaNodes);
                joinRegion.getJoinSourceNodes().remove(accessNode1);
                joinRegion.getJoinSourceNodes().remove(accessNode2);
                accessNodes.remove(i);
                accessNodes.remove(k < i ? k : k - 1);
                // build a new join node
                PlanNode joinNode = createJoinNode(accessNode1, accessNode2, joinCriteria, joinType);
                PlanNode newAccess = RuleRaiseAccess.raiseAccessOverJoin(joinNode, joinNode.getFirstChild(), entry.getKey(), capFinder, metadata, false);
                for (PlanNode critNode : joinCriteriaNodes) {
                    critNode.removeFromParent();
                    critNode.removeAllChildren();
                }
                for (Set<PlanNode> source : joinRegion.getCritieriaToSourceMap().values()) {
                    if (source.remove(accessNode1) || source.remove(accessNode2)) {
                        source.add(newAccess);
                    }
                }
                joinRegion.getJoinSourceNodes().put(newAccess, newAccess);
                accessNodes.add(newAccess);
                i = accessNodes.size();
                k = accessNodes.size();
                break;
            }
            if (discoveredJoin != -1) {
                // rerun with the discoveredJoin criteria
                i++;
                secondPass = discoveredJoin;
            }
        }
    }
    if (structureChanged) {
        joinRegion.reconstructJoinRegoin();
    }
}
Also used : JoinType(org.teiid.query.sql.lang.JoinType) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Example 4 with SupportedJoinCriteria

use of org.teiid.translator.ExecutionFactory.SupportedJoinCriteria in project teiid by teiid.

the class CapabilitiesUtil method getSupportedJoinCriteria.

public static SupportedJoinCriteria getSupportedJoinCriteria(Object modelID, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
    if (metadata.isVirtualModel(modelID)) {
        return SupportedJoinCriteria.ANY;
    }
    SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
    SupportedJoinCriteria crits = (SupportedJoinCriteria) caps.getSourceProperty(Capability.JOIN_CRITERIA_ALLOWED);
    if (crits == null) {
        return SupportedJoinCriteria.ANY;
    }
    return crits;
}
Also used : SupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities)

Aggregations

SupportedJoinCriteria (org.teiid.translator.ExecutionFactory.SupportedJoinCriteria)4 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)3 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)3 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)2 Criteria (org.teiid.query.sql.lang.Criteria)2 Expression (org.teiid.query.sql.symbol.Expression)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 Set (java.util.Set)1 SourceCapabilities (org.teiid.query.optimizer.capabilities.SourceCapabilities)1 JoinType (org.teiid.query.sql.lang.JoinType)1 Evaluatable (org.teiid.query.sql.lang.SubqueryContainer.Evaluatable)1 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)1 SymbolMap (org.teiid.query.sql.util.SymbolMap)1