Search in sources :

Example 16 with Criteria

use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.

the class JoinRegion method initializeJoinInformation.

/**
 *  Initializes information on the joinRegion about dependency information, etc.
 *
 *  TODO: assumptions are made here about how dependent criteria must look that are a little restrictive
 */
public void initializeJoinInformation() {
    critieriaToSourceMap = new HashMap<PlanNode, Set<PlanNode>>();
    LinkedList<PlanNode> crits = new LinkedList<PlanNode>(criteriaNodes);
    crits.addAll(dependentCritieraNodes);
    LinkedHashMap<PlanNode, PlanNode> source = new LinkedHashMap<PlanNode, PlanNode>(joinSourceNodes);
    source.putAll(dependentJoinSourceNodes);
    for (PlanNode critNode : crits) {
        for (GroupSymbol group : critNode.getGroups()) {
            for (PlanNode node : source.keySet()) {
                if (node.getGroups().contains(group)) {
                    Set<PlanNode> sources = critieriaToSourceMap.get(critNode);
                    if (sources == null) {
                        sources = new HashSet<PlanNode>();
                        critieriaToSourceMap.put(critNode, sources);
                    }
                    sources.add(node);
                    break;
                }
            }
        }
    }
    if (unsatisfiedAccessPatterns.isEmpty()) {
        return;
    }
    Map<GroupSymbol, PlanNode> dependentGroupToSourceMap = new HashMap<GroupSymbol, PlanNode>();
    for (PlanNode node : dependentJoinSourceNodes.keySet()) {
        for (GroupSymbol symbol : node.getGroups()) {
            dependentGroupToSourceMap.put(symbol, node);
        }
    }
    for (Iterator<PlanNode> i = getCriteriaNodes().iterator(); i.hasNext(); ) {
        PlanNode node = i.next();
        for (GroupSymbol symbol : node.getGroups()) {
            if (dependentGroupToSourceMap.containsKey(symbol)) {
                i.remove();
                dependentCritieraNodes.add(node);
                break;
            }
        }
    }
    dependentCriteriaElements = new HashMap<ElementSymbol, Set<Collection<GroupSymbol>>>();
    for (PlanNode critNode : dependentCritieraNodes) {
        Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
        if (!(crit instanceof CompareCriteria)) {
            continue;
        }
        CompareCriteria compCrit = (CompareCriteria) crit;
        if (compCrit.getOperator() != CompareCriteria.EQ) {
            continue;
        }
        CompareCriteria compareCriteria = (CompareCriteria) crit;
        // this may be a proper dependent join criteria
        Collection<ElementSymbol>[] critElements = new Collection[2];
        critElements[0] = ElementCollectorVisitor.getElements(compareCriteria.getLeftExpression(), true);
        if (critElements[0].isEmpty()) {
            continue;
        }
        critElements[1] = ElementCollectorVisitor.getElements(compareCriteria.getRightExpression(), true);
        if (critElements[1].isEmpty()) {
            continue;
        }
        for (int expr = 0; expr < critElements.length; expr++) {
            // simplifying assumption that there will be a single element on the dependent side
            if (critElements[expr].size() != 1) {
                continue;
            }
            ElementSymbol elem = critElements[expr].iterator().next();
            if (!dependentGroupToSourceMap.containsKey(elem.getGroupSymbol())) {
                continue;
            }
            // this is also a simplifying assumption.  don't consider criteria that can't be pushed
            if (containsFunctionsThatCannotBePushed(expr == 0 ? compareCriteria.getRightExpression() : compareCriteria.getLeftExpression())) {
                continue;
            }
            Set<Collection<GroupSymbol>> independentGroups = dependentCriteriaElements.get(elem);
            if (independentGroups == null) {
                independentGroups = new HashSet<Collection<GroupSymbol>>();
                dependentCriteriaElements.put(elem, independentGroups);
            }
            // set the other side as independent elements
            independentGroups.add(GroupsUsedByElementsVisitor.getGroups(critElements[(expr + 1) % 2]));
        }
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol)

Example 17 with Criteria

use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.

the class JoinRegion method getDepJoinCost.

private Float getDepJoinCost(QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context, PlanNode indNode, List<PlanNode> applicableCriteria, PlanNode depNode) throws QueryMetadataException, TeiidComponentException, QueryPlannerException {
    if (depNode.hasBooleanProperty(Info.MAKE_NOT_DEP)) {
        return null;
    }
    float indCost = indNode.getCardinality();
    if (indCost == NewCalculateCostUtil.UNKNOWN_VALUE) {
        return null;
    }
    List<Criteria> crits = new ArrayList<Criteria>(applicableCriteria.size());
    for (PlanNode planNode : applicableCriteria) {
        crits.add((Criteria) planNode.getProperty(NodeConstants.Info.SELECT_CRITERIA));
    }
    List<Expression> leftExpressions = new LinkedList<Expression>();
    List<Expression> rightExpressions = new LinkedList<Expression>();
    RuleChooseJoinStrategy.separateCriteria(indNode.getGroups(), depNode.getGroups(), leftExpressions, rightExpressions, crits, new LinkedList<Criteria>());
    if (leftExpressions.isEmpty()) {
        return null;
    }
    return NewCalculateCostUtil.computeCostForDepJoin(indNode, depNode, leftExpressions, rightExpressions, metadata, capFinder, context).expectedCardinality;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) Expression(org.teiid.query.sql.symbol.Expression) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 18 with Criteria

use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.

the class JoinRegion method estimateCriteriaSelectivity.

/**
 * @param metadata
 * @throws QueryMetadataException
 * @throws TeiidComponentException
 */
private void estimateCriteriaSelectivity(QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
    for (PlanNode node : criteriaNodes) {
        Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
        float[] baseCosts = new float[] { 100, 10000, 1000000 };
        float filterValue = 0;
        for (int j = 0; j < baseCosts.length; j++) {
            float filter = NewCalculateCostUtil.recursiveEstimateCostOfCriteria(baseCosts[j], node, crit, metadata);
            filterValue += filter / baseCosts[j];
        }
        filterValue /= baseCosts.length;
        node.setProperty(NodeConstants.Info.EST_SELECTIVITY, new Float(filterValue));
    }
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 19 with Criteria

use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.

the class JoinUtil method optimizeJoinType.

/**
 * Will attempt to optimize the join type based upon the criteria provided.
 *
 * Returns the new join type if one is found, otherwise null
 *
 * An outer join can be optimized if criteria that is not dependent upon null values
 * is applied on the inner side of the join.
 *
 * @param critNode
 * @param joinNode
 * @return
 */
static final JoinType optimizeJoinType(PlanNode critNode, PlanNode joinNode, QueryMetadataInterface metadata, boolean modifyJoin) {
    if (critNode.getGroups().isEmpty() || !joinNode.getGroups().containsAll(critNode.getGroups()) || joinNode.hasBooleanProperty(Info.PRESERVE)) {
        return null;
    }
    JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
    if (!joinType.isOuter()) {
        return null;
    }
    PlanNode left = joinNode.getFirstChild();
    left = FrameUtil.findJoinSourceNode(left);
    PlanNode right = joinNode.getLastChild();
    right = FrameUtil.findJoinSourceNode(right);
    Collection<GroupSymbol> outerGroups = left.getGroups();
    Collection<GroupSymbol> innerGroups = right.getGroups();
    if (joinType == JoinType.JOIN_RIGHT_OUTER) {
        outerGroups = innerGroups;
        innerGroups = left.getGroups();
    }
    // sanity check
    if ((joinType == JoinType.JOIN_LEFT_OUTER || joinType == JoinType.JOIN_RIGHT_OUTER) && outerGroups.containsAll(critNode.getGroups())) {
        return null;
    }
    Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
    boolean isNullDepdendent = isNullDependent(metadata, innerGroups, crit);
    JoinType result = JoinType.JOIN_INNER;
    if (joinType == JoinType.JOIN_LEFT_OUTER || joinType == JoinType.JOIN_RIGHT_OUTER) {
        if (isNullDepdendent) {
            return null;
        }
    } else {
        boolean isNullDepdendentOther = isNullDependent(metadata, outerGroups, crit);
        if (isNullDepdendent && isNullDepdendentOther) {
            return null;
        }
        if (isNullDepdendent && !isNullDepdendentOther) {
            result = JoinType.JOIN_LEFT_OUTER;
        } else if (!isNullDepdendent && isNullDepdendentOther) {
            if (modifyJoin) {
                JoinUtil.swapJoinChildren(joinNode);
                result = JoinType.JOIN_LEFT_OUTER;
            }
        }
    }
    if (modifyJoin) {
        joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, result);
    }
    return result;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) JoinType(org.teiid.query.sql.lang.JoinType) Criteria(org.teiid.query.sql.lang.Criteria)

Example 20 with Criteria

use of org.teiid.query.sql.lang.Criteria in project teiid by teiid.

the class RuleAssignOutputElements method collectRequiredInputSymbols.

/**
 * Collect all required input symbols for a given node.  Input symbols
 * are any symbols that are required in the processing of this node,
 * for instance to create a new element symbol or sort on it, etc.
 * @param node Node to collect for
 * @param metadata
 * @param capFinder
 * @throws TeiidComponentException
 * @throws QueryMetadataException
 */
private List<Expression> collectRequiredInputSymbols(PlanNode node, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
    Set<Expression> requiredSymbols = new LinkedHashSet<Expression>();
    Set<Expression> createdSymbols = new HashSet<Expression>();
    List<Expression> outputCols = (List<Expression>) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
    switch(node.getType()) {
        case NodeConstants.Types.PROJECT:
            {
                List<Expression> projectCols = (List<Expression>) node.getProperty(NodeConstants.Info.PROJECT_COLS);
                PlanNode accessParent = NodeEditor.findParent(node, NodeConstants.Types.ACCESS);
                PlanNode accessNode = null;
                if (accessParent == null) {
                    // find the direct access node
                    accessNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.ACCESS, NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN | NodeConstants.Types.SET_OP | NodeConstants.Types.GROUP);
                }
                for (Expression ss : projectCols) {
                    if (ss instanceof AliasSymbol) {
                        createdSymbols.add(ss);
                        ss = ((AliasSymbol) ss).getSymbol();
                    }
                    if (ss instanceof WindowFunction || ss instanceof ExpressionSymbol) {
                        createdSymbols.add(ss);
                    }
                    if (!pushProjection(node, metadata, capFinder, requiredSymbols, accessParent, accessNode, ss)) {
                        ElementCollectorVisitor.getElements(ss, requiredSymbols);
                    }
                }
                break;
            }
        case NodeConstants.Types.SELECT:
            Criteria selectCriteria = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
            ElementCollectorVisitor.getElements(selectCriteria, requiredSymbols);
            break;
        case NodeConstants.Types.JOIN:
            List<Criteria> crits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
            if (crits != null) {
                for (Criteria joinCriteria : crits) {
                    ElementCollectorVisitor.getElements(joinCriteria, requiredSymbols);
                }
            }
            break;
        case NodeConstants.Types.GROUP:
            List<Expression> groupCols = (List<Expression>) node.getProperty(NodeConstants.Info.GROUP_COLS);
            PlanNode accessParent = NodeEditor.findParent(node, NodeConstants.Types.ACCESS);
            PlanNode accessNode = null;
            if (accessParent == null) {
                // find the direct access node
                accessNode = NodeEditor.findNodePreOrder(node.getFirstChild(), NodeConstants.Types.ACCESS, NodeConstants.Types.SOURCE | NodeConstants.Types.JOIN | NodeConstants.Types.SET_OP | NodeConstants.Types.GROUP);
            }
            if (groupCols != null) {
                for (Expression expression : groupCols) {
                    if (!pushProjection(node, metadata, capFinder, requiredSymbols, accessParent, accessNode, expression)) {
                        ElementCollectorVisitor.getElements(expression, requiredSymbols);
                    }
                }
            }
            SymbolMap symbolMap = (SymbolMap) node.getProperty(NodeConstants.Info.SYMBOL_MAP);
            Set<ElementSymbol> usedAggregates = new HashSet<ElementSymbol>();
            // Take credit for creating any aggregates that are needed above
            for (Expression outputSymbol : outputCols) {
                if (!(outputSymbol instanceof ElementSymbol)) {
                    continue;
                }
                createdSymbols.add(outputSymbol);
                Expression ex = symbolMap.getMappedExpression((ElementSymbol) outputSymbol);
                if (ex instanceof AggregateSymbol) {
                    AggregateSymbol agg = (AggregateSymbol) ex;
                    Expression[] aggExprs = agg.getArgs();
                    for (Expression expression : aggExprs) {
                        if (!pushProjection(node, metadata, capFinder, requiredSymbols, accessParent, accessNode, expression)) {
                            ElementCollectorVisitor.getElements(expression, requiredSymbols);
                        }
                    }
                    OrderBy orderBy = agg.getOrderBy();
                    if (orderBy != null) {
                        ElementCollectorVisitor.getElements(orderBy, requiredSymbols);
                    }
                    Expression condition = agg.getCondition();
                    if (condition != null) {
                        ElementCollectorVisitor.getElements(condition, requiredSymbols);
                    }
                    usedAggregates.add((ElementSymbol) outputSymbol);
                }
            }
            // update the aggs in the symbolmap
            for (Map.Entry<ElementSymbol, Expression> entry : new ArrayList<Map.Entry<ElementSymbol, Expression>>(symbolMap.asMap().entrySet())) {
                if (entry.getValue() instanceof AggregateSymbol && !usedAggregates.contains(entry.getKey())) {
                    symbolMap.asUpdatableMap().remove(entry.getKey());
                }
            }
            if (requiredSymbols.isEmpty() && usedAggregates.isEmpty()) {
                node.setProperty(Info.IS_OPTIONAL, true);
            }
            break;
    }
    // Gather elements from correlated subquery references;
    for (SymbolMap refs : node.getAllReferences()) {
        for (Expression expr : refs.asMap().values()) {
            ElementCollectorVisitor.getElements(expr, requiredSymbols);
        }
    }
    // Add any columns to required that are in this node's output but were not created here
    for (Expression currentOutputSymbol : outputCols) {
        if (!createdSymbols.contains(currentOutputSymbol) && (finalRun || node.getType() != NodeConstants.Types.PROJECT || currentOutputSymbol instanceof ElementSymbol)) {
            requiredSymbols.add(currentOutputSymbol);
        }
    }
    // TODO: this should depend upon whether the expressions are deterministic
    if (node.getType() == NodeConstants.Types.PROJECT) {
        Set<Expression> expressions = new HashSet<Expression>();
        for (Iterator<Expression> iterator = requiredSymbols.iterator(); iterator.hasNext(); ) {
            Expression ses = iterator.next();
            if (!expressions.add(SymbolMap.getExpression(ses))) {
                iterator.remove();
            }
        }
    }
    return new ArrayList<Expression>(requiredSymbols);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) OrderBy(org.teiid.query.sql.lang.OrderBy) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) ArrayList(java.util.ArrayList) SymbolMap(org.teiid.query.sql.util.SymbolMap) ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol) Criteria(org.teiid.query.sql.lang.Criteria) WindowFunction(org.teiid.query.sql.symbol.WindowFunction) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) AliasSymbol(org.teiid.query.sql.symbol.AliasSymbol) Expression(org.teiid.query.sql.symbol.Expression) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) SymbolMap(org.teiid.query.sql.util.SymbolMap) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

Criteria (org.teiid.query.sql.lang.Criteria)67 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)40 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)35 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)22 Expression (org.teiid.query.sql.symbol.Expression)22 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)22 CompoundCriteria (org.teiid.query.sql.lang.CompoundCriteria)19 ArrayList (java.util.ArrayList)16 List (java.util.List)15 DependentSetCriteria (org.teiid.query.sql.lang.DependentSetCriteria)13 IsNullCriteria (org.teiid.query.sql.lang.IsNullCriteria)12 Constant (org.teiid.query.sql.symbol.Constant)11 SymbolMap (org.teiid.query.sql.util.SymbolMap)11 JoinType (org.teiid.query.sql.lang.JoinType)10 SetCriteria (org.teiid.query.sql.lang.SetCriteria)10 LinkedList (java.util.LinkedList)7 Reference (org.teiid.query.sql.symbol.Reference)6 LinkedHashSet (java.util.LinkedHashSet)5 LanguageObject (org.teiid.query.sql.LanguageObject)5 Collection (java.util.Collection)4