Search in sources :

Example 96 with PlanNode

use of org.teiid.query.optimizer.relational.plantree.PlanNode in project teiid by teiid.

the class RelationalPlanner method addNestedCommand.

private void addNestedCommand(PlanNode node, GroupSymbol group, Command nestedCommand, Command toPlan, boolean merge, boolean isStackEntry) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
    if (nestedCommand instanceof QueryCommand) {
        // remove unnecessary order by
        QueryCommand queryCommand = (QueryCommand) nestedCommand;
        if (queryCommand.getLimit() == null) {
            queryCommand.setOrderBy(null);
        }
    }
    Set<PlanningStackEntry> entries = null;
    PlanningStackEntry entry = null;
    if (isStackEntry) {
        entries = planningStack.get();
        entry = createPlanningStackEntry(group, nestedCommand, toPlan.getType() == Command.TYPE_UPDATE_PROCEDURE, entries);
    }
    try {
        node.setProperty(NodeConstants.Info.NESTED_COMMAND, nestedCommand);
        if (merge) {
            mergeTempMetadata(nestedCommand, parentCommand);
            PlanNode childRoot = generatePlan(nestedCommand);
            node.addFirstChild(childRoot);
            List<Expression> projectCols = nestedCommand.getProjectedSymbols();
            SymbolMap map = SymbolMap.createSymbolMap(group, projectCols, metadata);
            node.setProperty(NodeConstants.Info.SYMBOL_MAP, map);
        } else {
            QueryMetadataInterface actualMetadata = metadata;
            if (actualMetadata instanceof TempMetadataAdapter) {
                actualMetadata = ((TempMetadataAdapter) metadata).getMetadata();
            }
            ProcessorPlan plan = QueryOptimizer.optimizePlan(toPlan, actualMetadata, idGenerator, capFinder, analysisRecord, context);
            // hack for the optimizer not knowing the containing command when forming the plan
            if (nestedCommand instanceof StoredProcedure && plan instanceof ProcedurePlan) {
                StoredProcedure container = (StoredProcedure) nestedCommand;
                ProcedurePlan pp = (ProcedurePlan) plan;
                pp.setUpdateCount(container.getUpdateCount());
                if (container.returnParameters()) {
                    List<ElementSymbol> outParams = new LinkedList<ElementSymbol>();
                    for (SPParameter param : container.getParameters()) {
                        if (param.getParameterType() == SPParameter.RETURN_VALUE) {
                            outParams.add(param.getParameterSymbol());
                        }
                    }
                    for (SPParameter param : container.getParameters()) {
                        if (param.getParameterType() == SPParameter.INOUT || param.getParameterType() == SPParameter.OUT) {
                            outParams.add(param.getParameterSymbol());
                        }
                    }
                    if (outParams.size() > 0) {
                        pp.setOutParams(outParams);
                    }
                }
                pp.setParams(container.getProcedureParameters());
            }
            node.setProperty(NodeConstants.Info.PROCESSOR_PLAN, plan);
        }
    } finally {
        if (entries != null) {
            entries.remove(entry);
        }
    }
}
Also used : TempMetadataAdapter(org.teiid.query.metadata.TempMetadataAdapter) SymbolMap(org.teiid.query.sql.util.SymbolMap) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) ProcedurePlan(org.teiid.query.processor.proc.ProcedurePlan) QueryMetadataInterface(org.teiid.query.metadata.QueryMetadataInterface) ProcessorPlan(org.teiid.query.processor.ProcessorPlan)

Example 97 with PlanNode

use of org.teiid.query.optimizer.relational.plantree.PlanNode in project teiid by teiid.

the class RelationalPlanner method distributeDependentHints.

/**
 * Distribute and "make (not) dependent" hints specified in the query into the
 * fully resolved query plan.  This is done after virtual group resolution so
 * that all groups in the plan are known.  The hint is attached to all SOURCE
 * nodes for each group that should be made dependent/not dependent.
 * @param groups List of groups (Strings) to be made dependent
 * @param plan The canonical plan
 */
private void distributeDependentHints(Collection<String> groups, PlanNode plan, NodeConstants.Info hintProperty, Collection<? extends Object> vals) throws QueryMetadataException, TeiidComponentException {
    if (groups == null || groups.isEmpty()) {
        return;
    }
    // Get all source nodes
    List<PlanNode> nodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE);
    Iterator<? extends Object> valIter = vals.iterator();
    // attach to the correct source node
    for (String groupName : groups) {
        Object val = valIter.next();
        // Walk through nodes and apply hint to all that match group name
        boolean appliedHint = false;
        if (groupName.startsWith("@")) {
            // $NON-NLS-1$
            appliedHint = applyGlobalTableHint(plan, hintProperty, groupName.substring(1), val);
        }
        if (!appliedHint) {
            appliedHint = applyHint(nodes, groupName, hintProperty, val);
        }
        if (!appliedHint) {
            // check if it is partial group name
            Collection groupNames = metadata.getGroupsForPartialName(groupName);
            if (groupNames.size() == 1) {
                groupName = (String) groupNames.iterator().next();
                appliedHint = applyHint(nodes, groupName, hintProperty, val);
            }
            if (!appliedHint && this.analysisRecord.recordAnnotations()) {
                // $NON-NLS-1$
                String msg = QueryPlugin.Util.getString("ERR.015.004.0010", groupName);
                // $NON-NLS-1$
                this.analysisRecord.addAnnotation(new Annotation(Annotation.HINTS, msg, "ignoring hint", Priority.MEDIUM));
            }
        }
    }
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) LanguageObject(org.teiid.query.sql.LanguageObject) Annotation(org.teiid.client.plan.Annotation)

Example 98 with PlanNode

use of org.teiid.query.optimizer.relational.plantree.PlanNode in project teiid by teiid.

the class RelationalPlanner method generatePlan.

public PlanNode generatePlan(Command cmd) throws TeiidComponentException, TeiidProcessingException {
    // cascade the option clause nocache
    Option savedOption = option;
    option = cmd.getOption();
    if (option == null) {
        if (savedOption != null) {
            option = savedOption;
        }
    } else if (savedOption != null && savedOption.isNoCache() && savedOption != option) {
        // merge no cache settings
        if (savedOption.getNoCacheGroups() == null || savedOption.getNoCacheGroups().isEmpty()) {
            if (option.getNoCacheGroups() != null) {
                // full no cache
                option.getNoCacheGroups().clear();
            }
        } else if (option.getNoCacheGroups() != null && !option.getNoCacheGroups().isEmpty()) {
            for (String noCache : savedOption.getNoCacheGroups()) {
                // only groups
                option.addNoCacheGroup(noCache);
            }
        }
        option.setNoCache(true);
    }
    PlanNode result = null;
    switch(cmd.getType()) {
        case Command.TYPE_QUERY:
            result = createQueryPlan((QueryCommand) cmd, null);
            break;
        case Command.TYPE_INSERT:
        case Command.TYPE_UPDATE:
        case Command.TYPE_DELETE:
        case Command.TYPE_CREATE:
        case Command.TYPE_DROP:
            result = createUpdatePlan(cmd);
            break;
        case Command.TYPE_STORED_PROCEDURE:
            result = createStoredProcedurePlan((StoredProcedure) cmd);
            break;
        default:
            // $NON-NLS-1$
            throw new AssertionError("Invalid command type");
    }
    // Distribute make dependent hints as necessary
    if (cmd.getOption() != null) {
        if (cmd.getOption().getMakeDepOptions() != null) {
            distributeDependentHints(cmd.getOption().getDependentGroups(), result, NodeConstants.Info.MAKE_DEP, cmd.getOption().getMakeDepOptions());
        }
        if (cmd.getOption().getNotDependentGroups() != null) {
            distributeDependentHints(cmd.getOption().getNotDependentGroups(), result, NodeConstants.Info.MAKE_NOT_DEP, Collections.nCopies(cmd.getOption().getNotDependentGroups().size(), Boolean.TRUE));
        }
    }
    this.option = savedOption;
    return result;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode)

Example 99 with PlanNode

use of org.teiid.query.optimizer.relational.plantree.PlanNode in project teiid by teiid.

the class RelationalPlanner method createStoredProcedurePlan.

PlanNode createStoredProcedurePlan(StoredProcedure storedProc) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException {
    // Create top project node - define output columns for stored query / procedure
    PlanNode projectNode = attachProject(null, storedProc.getProjectedSymbols());
    // Define source of data for stored query / procedure
    PlanNode sourceNode = NodeFactory.getNewNode(NodeConstants.Types.SOURCE);
    sourceNode.setProperty(NodeConstants.Info.VIRTUAL_COMMAND, storedProc);
    addNestedProcedure(sourceNode, storedProc, storedProc.getProcedureID());
    hints.hasRelationalProc |= storedProc.isProcedureRelational();
    if (!hints.hasRowBasedSecurity && RowBasedSecurityHelper.applyRowSecurity(metadata, storedProc.getGroup(), context)) {
        hints.hasRowBasedSecurity = true;
    }
    // Set group on source node
    sourceNode.addGroup(storedProc.getGroup());
    attachLast(projectNode, sourceNode);
    return projectNode;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode)

Example 100 with PlanNode

use of org.teiid.query.optimizer.relational.plantree.PlanNode in project teiid by teiid.

the class RelationalPlanner method applyHint.

private static boolean applyHint(List<PlanNode> nodes, String groupName, NodeConstants.Info hintProperty, Object value) {
    boolean appliedHint = false;
    for (PlanNode node : nodes) {
        GroupSymbol nodeGroup = node.getGroups().iterator().next();
        String sDefinition = nodeGroup.getDefinition();
        if (nodeGroup.getName().equalsIgnoreCase(groupName) || (sDefinition != null && sDefinition.equalsIgnoreCase(groupName))) {
            node.setProperty(hintProperty, value);
            appliedHint = true;
        }
    }
    return appliedHint;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode)

Aggregations

PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)204 Expression (org.teiid.query.sql.symbol.Expression)50 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)50 ArrayList (java.util.ArrayList)47 List (java.util.List)43 SymbolMap (org.teiid.query.sql.util.SymbolMap)42 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)36 Criteria (org.teiid.query.sql.lang.Criteria)35 LinkedList (java.util.LinkedList)24 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)24 Test (org.junit.Test)22 HashSet (java.util.HashSet)17 JoinType (org.teiid.query.sql.lang.JoinType)17 LinkedHashSet (java.util.LinkedHashSet)16 CompoundCriteria (org.teiid.query.sql.lang.CompoundCriteria)12 DependentSetCriteria (org.teiid.query.sql.lang.DependentSetCriteria)12 QueryPlannerException (org.teiid.api.exception.query.QueryPlannerException)11 LanguageObject (org.teiid.query.sql.LanguageObject)11 OrderBy (org.teiid.query.sql.lang.OrderBy)10 IsNullCriteria (org.teiid.query.sql.lang.IsNullCriteria)9