Examples of PlanNode


Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

     * the groups that originate under the node on the NULL node
     * 
     * @param node
     */
    static void replaceWithNullNode(PlanNode node) {
        PlanNode nullNode = NodeFactory.getNewNode(NodeConstants.Types.NULL);
        PlanNode source = FrameUtil.findJoinSourceNode(node);
        if (source != null) {
            nullNode.addGroups(source.getGroups());
        }
        node.getParent().replaceChild(node, nullNode);
    }
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

     *
     * @param accessNode
     * @return
     */
    static ProcessorPlan getNestedPlan(PlanNode accessNode) {
        PlanNode sourceNode = accessNode.getFirstChild();
        if (sourceNode == null) {
          return null;
        }
        if(sourceNode.getType() != NodeConstants.Types.SOURCE) {
            sourceNode = sourceNode.getFirstChild();
        }
        if(sourceNode != null && sourceNode.getType() == NodeConstants.Types.SOURCE) {
            return (ProcessorPlan) sourceNode.getProperty(NodeConstants.Info.PROCESSOR_PLAN);
        }
        return null;           
    }
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

     *
     * @param accessNode
     * @return The actual stored procedure
     */
    static Command getNonQueryCommand(PlanNode node) {
        PlanNode sourceNode = node.getFirstChild();
        if (sourceNode == null) {
          return null;
        }
        if(sourceNode.getType() != NodeConstants.Types.SOURCE) {
            sourceNode = sourceNode.getFirstChild();
        }
        if(sourceNode != null && sourceNode.getType() == NodeConstants.Types.SOURCE) {
            Command command = (Command) sourceNode.getProperty(NodeConstants.Info.VIRTUAL_COMMAND);
            if(! (command instanceof QueryCommand)) {
                return command;
            }               
        }
        return null;
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

        return null;
    }
   
    static boolean isProcedure(PlanNode projectNode) {
        if(projectNode.getType() == NodeConstants.Types.PROJECT && projectNode.getChildCount() > 0) {
            PlanNode accessNode = projectNode.getFirstChild();
            Command command = getNonQueryCommand(accessNode);
            return command instanceof StoredProcedure;
        }
        return false;
    }
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

   
    /**
     * Finds the closest project columns in the current frame
     */
    static List<SingleElementSymbol> findTopCols(PlanNode node) {
      PlanNode project = NodeEditor.findNodePreOrder(node, NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE);
        if (project == null) {
            project = NodeEditor.findParent(node, NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE);
        }
        if (project != null) {
            return (List<SingleElementSymbol>)project.getProperty(NodeConstants.Info.PROJECT_COLS);
        }
        Assertion.failed("no top cols in frame"); //$NON-NLS-1$
        return null;
    }
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

        List<PlanNode> limitNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.TUPLE_LIMIT);
       
        boolean pushRaiseNull = false;
       
        while (!limitNodes.isEmpty()) {
            PlanNode limitNode = limitNodes.get(0);
           
            Expression limit = (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
           
            if (limit instanceof Constant && new Integer(0).equals(((Constant)limit).getValue())) {
                PlanNode childProject = NodeEditor.findNodePreOrder(limitNode, NodeConstants.Types.PROJECT);
               
                if (childProject != null && childProject.getProperty(NodeConstants.Info.INTO_GROUP) == null) {
                    FrameUtil.replaceWithNullNode(limitNode.getFirstChild());
                    PlanNode projectNode = NodeFactory.getNewNode(NodeConstants.Types.PROJECT);
                    projectNode.setProperty(NodeConstants.Info.PROJECT_COLS, childProject.getProperty(NodeConstants.Info.PROJECT_COLS));
                    limitNode.getFirstChild().addAsParent(projectNode);
                    pushRaiseNull = true;
                    limitNodes.remove(limitNode);
                    continue;
                }
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

       
        return plan;
    }
   
    boolean canPushLimit(PlanNode rootNode, PlanNode limitNode, List<PlanNode> limitNodes, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
        PlanNode child = limitNode.getFirstChild();
        if (child == null || child.getChildCount() == 0) {
            return false;
        }
       
        Expression parentLimit = (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
    Expression parentOffset = (Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
    switch (child.getType()) {
            case NodeConstants.Types.TUPLE_LIMIT:
            {
             
                //combine the limits
                Expression childLimit = (Expression)child.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
        Expression childOffset = (Expression)child.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
       
        combineLimits(limitNode, metadata, parentLimit, parentOffset, childLimit, childOffset);
               
                NodeEditor.removeChildNode(limitNode, child);
                limitNodes.remove(child);
               
                return canPushLimit(rootNode, limitNode, limitNodes, metadata, capFinder);
            }
            case NodeConstants.Types.SET_OP:
            {
                if (!SetQuery.Operation.UNION.equals(child.getProperty(NodeConstants.Info.SET_OPERATION))
                    || !child.hasBooleanProperty(NodeConstants.Info.USE_ALL)) {
                    return false;
                }                               
                //distribute the limit
                List<PlanNode> grandChildren = new LinkedList<PlanNode>(child.getChildren());
                for (PlanNode grandChild : grandChildren) {
                    PlanNode newLimit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
                    newLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, op(SourceSystemFunctions.ADD_OP, parentLimit, parentOffset, metadata.getFunctionLibrary()));
                    grandChild.addAsParent(newLimit);
                    limitNodes.add(newLimit);
                }
               
                return false;
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

        if (offset != null && !CapabilitiesUtil.supportsRowOffset(modelID, metadata, capFinder)) {
           
            if (limit != null) {
                parentNode.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, null);
               
                PlanNode pushedLimit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
               
                // since we're pushing underneath the offset, we want enough rows to satisfy both the limit and the row offset
               
                pushedLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, op(SourceSystemFunctions.ADD_OP, limit, offset, metadata.getFunctionLibrary()));
               
                if (accessNode.getChildCount() == 0) {
                    accessNode.addFirstChild(pushedLimit);
                } else {
                    accessNode.getFirstChild().addAsParent(pushedLimit);
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

        boolean raisedNode = true;
        while(raisedNode) {
            raisedNode = false;

            for (PlanNode accessNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.ACCESS)) {
                PlanNode newRoot = raiseAccessNode(plan, accessNode, metadata, capFinder, afterJoinPlanning, analysisRecord);
                if(newRoot != null) {
                    raisedNode = true;
                    plan = newRoot;
                }
            }           
View Full Code Here

Examples of org.teiid.query.optimizer.relational.plantree.PlanNode

     */
    static PlanNode raiseAccessNode(PlanNode rootNode, PlanNode accessNode, QueryMetadataInterface metadata,
        CapabilitiesFinder capFinder, boolean afterJoinPlanning, AnalysisRecord record)
    throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
       
        PlanNode parentNode = accessNode.getParent();
        if(parentNode == null) {
            // Nothing to raise over
            return null;
        }
        Object modelID = getModelIDFromAccess(accessNode, metadata);
        if(modelID == null) {
            return null;
        }
       
        switch(parentNode.getType()) {
            case NodeConstants.Types.JOIN:
            {
                modelID = canRaiseOverJoin(modelID, parentNode, metadata, capFinder, afterJoinPlanning, record);
                if(modelID != null) {
                    raiseAccessOverJoin(parentNode, modelID, true);                   
                    return rootNode;
                }
                return null;
            }           
            case NodeConstants.Types.PROJECT:
            {        
                // Check that the PROJECT contains only functions that can be pushed                              
                List projectCols = (List) parentNode.getProperty(NodeConstants.Info.PROJECT_COLS);
               
                for (int i = 0; i < projectCols.size(); i++) {
                    SingleElementSymbol symbol = (SingleElementSymbol)projectCols.get(i);
                    if(! canPushSymbol(symbol, true, modelID, metadata, capFinder, record)) {
                        return null;
                    }
                }
               
                /*
                 * TODO: this creates an extraneous project node in many circumstances.
                 * However we don't actually support project in this case, so allowing it to be pushed
                 * causes problems with stored procedures and the assumptions made for proc/relational
                 * planning.
                 */
                if (FrameUtil.isProcedure(parentNode)) {
                  return null;
                }
                               
                return performRaise(rootNode, accessNode, parentNode);               
            }
            case NodeConstants.Types.DUP_REMOVE:
            {    
                // If model supports the support constant parameter, then move access node
                if(!CapabilitiesUtil.supportsSelectDistinct(modelID, metadata, capFinder)) {
                  recordDebug("cannot push dupremove, since distinct is not supported by source", parentNode, record); //$NON-NLS-1$
                  return null;
                }
               
                //TODO: this check is too specific the columns could be used in expressions that are comparable
                if (!CapabilitiesUtil.checkElementsAreSearchable((List)NodeEditor.findNodePreOrder(parentNode, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS), metadata, SupportConstants.Element.SEARCHABLE_COMPARE)) {
                  recordDebug("cannot push dupremove, since not all columns are comparable at the source", parentNode, record); //$NON-NLS-1$
                  return null;
                }
               
                return performRaise(rootNode, accessNode, parentNode);
            }
            case NodeConstants.Types.SORT:
            {        
                if (canRaiseOverSort(accessNode, metadata, capFinder, parentNode, record, false)) {
                    return performRaise(rootNode, accessNode, parentNode);
                }
                return null;
            }           
            case NodeConstants.Types.GROUP:           
            {               
                Set<AggregateSymbol> aggregates = RulePushAggregates.collectAggregates(parentNode);
                if (canRaiseOverGroupBy(parentNode, accessNode, aggregates, metadata, capFinder, record)) {
                    return performRaise(rootNode, accessNode, parentNode);
                }
                return null;
            }
            case NodeConstants.Types.SET_OP:
              if (!canRaiseOverSetQuery(parentNode, metadata, capFinder)) {
                return null;
              }

              for (PlanNode node : new ArrayList<PlanNode>(parentNode.getChildren())) {
                if (node == accessNode) {
                  continue;
                }
              NodeEditor.removeChildNode(parentNode, node);
              }
              accessNode.getGroups().clear();
                return performRaise(rootNode, accessNode, parentNode);
            case NodeConstants.Types.SELECT:           
            {
              if (parentNode.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
                return null;
              }
              if (canRaiseOverSelect(accessNode, metadata, capFinder, parentNode, record)) {
                    RulePushSelectCriteria.satisfyAccessPatterns(parentNode, accessNode);
                    return performRaise(rootNode, accessNode, parentNode);                     
              }
              //determine if we should push the select back up
              if (parentNode.getParent() == null) {
                return null;
              }
            PlanNode selectRoot = parentNode;
            while (selectRoot.getParent() != null && selectRoot.getParent().getType() == NodeConstants.Types.SELECT) {
              selectRoot = selectRoot.getParent();
            }
            if (selectRoot.getParent() == null || (selectRoot.getParent().getType() & (NodeConstants.Types.PROJECT|NodeConstants.Types.GROUP)) == selectRoot.getParent().getType()) {
              return null;
            }
          PlanNode grandParent = selectRoot.getParent();
          boolean isLeft = false;
        isLeft = grandParent.getFirstChild() == selectRoot;
        if (grandParent.getType() == NodeConstants.Types.JOIN) {
          JoinType jt = (JoinType)grandParent.getProperty(NodeConstants.Info.JOIN_TYPE);
          if (jt == JoinType.JOIN_FULL_OUTER || (jt == JoinType.JOIN_LEFT_OUTER && !isLeft)) {
            return null;
          }
        }
        grandParent.removeChild(selectRoot);
        if (isLeft) {
          grandParent.addFirstChild(accessNode);
        } else {
          grandParent.addLastChild(accessNode);
        }
          PlanNode newParent = grandParent.getParent();
        //TODO: use costing or heuristics instead of always raising
          PlanNode newRoot = raiseAccessNode(rootNode, accessNode, metadata, capFinder, afterJoinPlanning, record);
          if (newRoot == null) {
          //return the tree to its original state
            parentNode.addFirstChild(accessNode);
            if (isLeft) {
              grandParent.addFirstChild(selectRoot);
            } else {
              grandParent.addLastChild(selectRoot);
            }
          } else {
            //attach the select nodes above the access node
            accessNode = grandParent.getParent();
          if (newParent != null) {
              isLeft = newParent.getFirstChild() == accessNode;
              if (isLeft) {
                newParent.addFirstChild(selectRoot);
              } else {
                newParent.addLastChild(selectRoot);
              }
            } else {
              newRoot = selectRoot;
            }
          parentNode.addFirstChild(accessNode);
            return newRoot;
          }
                return null;
            }  
            case NodeConstants.Types.SOURCE:
            {
                //if a source has access patterns that are unsatisfied, then the raise cannot occur
                if (parentNode.hasCollectionProperty(NodeConstants.Info.ACCESS_PATTERNS)) {
                    return null;
                }
               
                SymbolMap references = (SymbolMap)parentNode.getProperty(NodeConstants.Info.CORRELATED_REFERENCES);
                if (references != null) {
                  return null;
                }
               
                //raise only if there is no intervening project into
                PlanNode parentProject = NodeEditor.findParent(parentNode, NodeConstants.Types.PROJECT);
                GroupSymbol intoGroup = (GroupSymbol)parentProject.getProperty(NodeConstants.Info.INTO_GROUP);
                if (intoGroup != null && parentProject.getParent() == null) {
                  if (CapabilitiesUtil.supports(Capability.INSERT_WITH_QUERYEXPRESSION, modelID, metadata, capFinder) && CapabilitiesUtil.isSameConnector(modelID, metadata.getModelID(intoGroup.getMetadataID()), metadata, capFinder)) {
                      rootNode = performRaise(rootNode, accessNode, parentNode);
                      return performRaise(rootNode, accessNode, parentProject);
                  }
                  return null;
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.