Search in sources :

Example 21 with Criteria

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

the class RulePushLargeIn method execute.

@Override
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    for (PlanNode critNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT, NodeConstants.Types.ACCESS)) {
        if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
            continue;
        }
        Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
        if (!(crit instanceof SetCriteria)) {
            continue;
        }
        SetCriteria setCriteria = (SetCriteria) crit;
        if (setCriteria.isNegated() || !setCriteria.isAllConstants()) {
            continue;
        }
        // we need to be directly over an access node
        PlanNode childAccess = critNode.getFirstChild();
        accessLoop: while (true) {
            switch(childAccess.getType()) {
                case NodeConstants.Types.ACCESS:
                    break accessLoop;
                case NodeConstants.Types.SELECT:
                    break;
                default:
                    break accessLoop;
            }
            childAccess = childAccess.getFirstChild();
        }
        if (childAccess.getType() != NodeConstants.Types.ACCESS) {
            continue;
        }
        // use a dummy value to test if we can raise
        critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new SetCriteria(setCriteria.getExpression(), Collections.EMPTY_LIST));
        boolean canRaise = RuleRaiseAccess.canRaiseOverSelect(childAccess, metadata, capabilitiesFinder, critNode, analysisRecord);
        critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
        if (!canRaise) {
            continue;
        }
        // push the crit node and mark as dependent set
        critNode.getParent().replaceChild(critNode, critNode.getFirstChild());
        childAccess.addAsParent(critNode);
        RuleRaiseAccess.performRaise(plan, childAccess, critNode);
        childAccess.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, true);
        childAccess.setProperty(NodeConstants.Info.EST_CARDINALITY, null);
    }
    return plan;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) SetCriteria(org.teiid.query.sql.lang.SetCriteria) Criteria(org.teiid.query.sql.lang.Criteria) SetCriteria(org.teiid.query.sql.lang.SetCriteria)

Example 22 with Criteria

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

the class RulePushLimit method getMinValue.

/**
 * @param limitNode
 * @param child
 * @throws TeiidComponentException
 * @throws BlockedException
 * @throws ExpressionEvaluationException
 */
static Expression getMinValue(Expression expr1, Expression expr2) {
    if (expr1 == null) {
        return expr2;
    }
    if (expr2 == null) {
        return expr1;
    }
    Criteria crit = new CompareCriteria(expr1, CompareCriteria.LT, expr2);
    SearchedCaseExpression sce = new SearchedCaseExpression(Arrays.asList(new Object[] { crit }), Arrays.asList(new Object[] { expr1 }));
    sce.setElseExpression(expr2);
    sce.setType(expr1.getType());
    return evaluateIfPossible(sce);
}
Also used : SearchedCaseExpression(org.teiid.query.sql.symbol.SearchedCaseExpression) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 23 with Criteria

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

the class RulePushNonJoinCriteria method execute.

/**
 * Execute the rule as described in the class comments.
 * @param plan Incoming query plan, may be modified during method and may be returned from method
 * @param metadata Metadata source
 * @param rules Rules from optimizer rule stack, may be manipulated during method
 * @return Updated query plan if rule fired, else original query plan
 */
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    boolean treeChanged = false;
    boolean removeCopiedFlag = false;
    boolean pushRuleRaiseNull = false;
    for (PlanNode node : NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN)) {
        List criteria = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
        JoinType joinType = (JoinType) node.getProperty(NodeConstants.Info.JOIN_TYPE);
        // criteria cannot be pushed out of a full outer join clause
        if (joinType == JoinType.JOIN_FULL_OUTER || joinType == JoinType.JOIN_CROSS) {
            continue;
        }
        Iterator crits = criteria.iterator();
        while (crits.hasNext()) {
            Criteria crit = (Criteria) crits.next();
            // special case handling for true/false criteria
            if (crit.equals(QueryRewriter.FALSE_CRITERIA) || crit.equals(QueryRewriter.UNKNOWN_CRITERIA)) {
                if (joinType == JoinType.JOIN_INNER) {
                    FrameUtil.replaceWithNullNode(node);
                } else {
                    // must be a left or right outer join, replace the inner side with null
                    FrameUtil.replaceWithNullNode(JoinUtil.getInnerSideJoinNodes(node)[0]);
                    removeCopiedFlag = true;
                }
                // since a null node has been created, raise it to its highest point
                pushRuleRaiseNull = true;
                treeChanged = true;
                break;
            } else if (crit.equals(QueryRewriter.TRUE_CRITERIA)) {
                crits.remove();
                break;
            }
            if (pushCriteria(node, crit, crits, metadata)) {
                treeChanged = true;
            }
        }
        // degrade the join if there is no criteria left
        if (criteria.isEmpty() && joinType == JoinType.JOIN_INNER) {
            node.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_CROSS);
            treeChanged = true;
        }
        if (removeCopiedFlag) {
            // allow the criteria above the join to be eligible for pushing and copying
            PlanNode parent = node.getParent();
            while (parent != null && parent.getType() == NodeConstants.Types.SELECT) {
                parent.setProperty(NodeConstants.Info.IS_COPIED, Boolean.FALSE);
                parent = parent.getParent();
            }
        }
    }
    if (treeChanged) {
        rules.push(RuleConstants.PUSH_SELECT_CRITERIA);
    }
    if (pushRuleRaiseNull) {
        rules.push(RuleConstants.RAISE_NULL);
    }
    return plan;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) Iterator(java.util.Iterator) JoinType(org.teiid.query.sql.lang.JoinType) ArrayList(java.util.ArrayList) List(java.util.List) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 24 with Criteria

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

the class RulePushSelectCriteria method moveNodeAcrossFrame.

Boolean moveNodeAcrossFrame(PlanNode critNode, PlanNode sourceNode, final QueryMetadataInterface metadata) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    // Check that sourceNode has a child to push across
    if (sourceNode.getChildCount() == 0) {
        return false;
    }
    final PlanNode projectNode = NodeEditor.findNodePreOrder(sourceNode.getFirstChild(), NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE);
    if (FrameUtil.isProcedure(projectNode)) {
        return false;
    }
    final SymbolMap symbolMap = (SymbolMap) sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
    final GroupSymbol sourceGroup = sourceNode.getGroups().iterator().next();
    if (!placeConvertedSelectNode(critNode, sourceGroup, projectNode, symbolMap, metadata)) {
        if (createdNodes == null) {
            Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
            if (isMultiAttributeDependentSet(crit) && splitSet(critNode, new DependentNodeTest() {

                @Override
                public boolean isValid(PlanNode copyNode) throws QueryMetadataException, QueryPlannerException, TeiidComponentException {
                    return createConvertedSelectNode(copyNode, sourceGroup, projectNode, symbolMap, metadata) != null;
                }
            }, (DependentSetCriteria) crit, sourceNode)) {
                return null;
            }
        }
        return false;
    }
    if (createdNodes == null) {
        satisfyConditions(critNode, sourceNode, metadata);
    }
    // Mark critNode as a "phantom"
    critNode.setProperty(NodeConstants.Info.IS_PHANTOM, Boolean.TRUE);
    return true;
}
Also used : DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) SymbolMap(org.teiid.query.sql.util.SymbolMap) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 25 with Criteria

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

the class RulePushSelectCriteria method markDependent.

private void markDependent(PlanNode critNode, PlanNode accessNode, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
    // once a dependent crit node is pushed, don't bother pushing it further into the command
    // dependent access node will use this as an assumption for where dependent sets can appear in the command
    critNode.setProperty(NodeConstants.Info.IS_PUSHED, Boolean.TRUE);
    if (createdNodes != null) {
        // this is during a planning run and should not cause additional side-effects
        return;
    }
    accessNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
    Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
    if (isMultiAttributeDependentSet(crit)) {
        // split the criteria as needed
        List<DependentSetCriteria> crits = splitDependentSetCriteria((DependentSetCriteria) crit, CapabilitiesUtil.supports(Capability.ARRAY_TYPE, RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata), metadata, capFinder), metadata);
        critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new CompoundCriteria(crits));
    }
    Collection<ElementSymbol> elements = null;
    for (PlanNode joinNode : NodeEditor.findAllNodes(accessNode, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE)) {
        List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.JOIN_CRITERIA);
        if (joinCriteria == null) {
            continue;
        }
        for (Criteria joinPredicate : joinCriteria) {
            if (!(joinPredicate instanceof CompareCriteria)) {
                continue;
            }
            CompareCriteria cc = (CompareCriteria) joinPredicate;
            if (!cc.isOptional()) {
                continue;
            }
            if (elements == null) {
                elements = ElementCollectorVisitor.getElements((LanguageObject) critNode.getProperty(Info.SELECT_CRITERIA), true);
            }
            if (!Collections.disjoint(elements, ElementCollectorVisitor.getElements(cc, false))) {
                cc.setOptional(false);
            }
        }
    }
}
Also used : DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) LanguageObject(org.teiid.query.sql.LanguageObject)

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