Search in sources :

Example 6 with QueryPlannerException

use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.

the class RuleCopyCriteria method copyCriteria.

/**
 * Given a criteria and a map of elements to values try to create a new single group criteria
 *
 * If the new criteria does not have exactly one group or already exists in the combined criteria,
 * it will not be added.
 *
 * @param crit
 * @param tgtMap
 * @param joinCriteria
 * @param combinedCriteria
 * @return number of remaining groups if the copy was successful
 */
private Integer copyCriteria(Criteria crit, Map<Expression, Expression> tgtMap, List<Criteria> joinCriteria, Set<Criteria> combinedCriteria, boolean checkForGroupReduction, QueryMetadataInterface metadata, boolean underAccess) {
    int startGroups = GroupsUsedByElementsVisitor.getGroups(crit).size();
    Criteria tgtCrit = (Criteria) crit.clone();
    try {
        tgtCrit = FrameUtil.convertCriteria(tgtCrit, tgtMap, metadata, true);
    } catch (QueryPlannerException err) {
        // $NON-NLS-1$
        LogManager.logDetail(LogConstants.CTX_QUERY_PLANNER, err, "Could not remap target criteria in RuleCopyCriteria");
        return null;
    }
    if (tgtCrit instanceof IsNullCriteria && ((IsNullCriteria) tgtCrit).isNegated()) {
        return null;
    }
    int endGroups = GroupsUsedByElementsVisitor.getGroups(tgtCrit).size();
    if (checkForGroupReduction) {
        if (endGroups >= startGroups) {
            return null;
        }
    } else if (endGroups > startGroups) {
        return null;
    }
    boolean isNew = combinedCriteria.add(tgtCrit);
    if (underAccess) {
        if (!isNew || checkForGroupReduction || endGroups > 1) {
            return null;
        }
        if (!COPY_ALL) {
            boolean use = false;
            Collection<ElementSymbol> cols = ElementCollectorVisitor.getElements(tgtCrit, true);
            // use only if it could be used to further rewrite predicates
            for (Criteria existing : combinedCriteria) {
                if (existing.equals(tgtCrit)) {
                    continue;
                }
                Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(existing, true);
                if (GroupsUsedByElementsVisitor.getGroups(elements).size() > 1) {
                    continue;
                }
                if (elements.containsAll(cols)) {
                    use = true;
                    break;
                }
            }
            if (!use) {
                return null;
            }
        }
    }
    // if this is unique or it a duplicate but reduced a current join conjunct, return true
    if (isNew) {
        joinCriteria.add(tgtCrit);
        if (tgtCrit instanceof CompareCriteria) {
            CompareCriteria cc = (CompareCriteria) tgtCrit;
            if (!EvaluatableVisitor.willBecomeConstant(cc.getRightExpression()) && !EvaluatableVisitor.willBecomeConstant(cc.getRightExpression())) {
                ((CompareCriteria) tgtCrit).setOptional(true);
            }
        }
        return endGroups;
    } else if (checkForGroupReduction && endGroups < 2) {
        return endGroups;
    }
    return null;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria)

Example 7 with QueryPlannerException

use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.

the class PlanToProcessConverter method convert.

public RelationalPlan convert(PlanNode planNode) throws QueryPlannerException, TeiidComponentException {
    try {
        boolean debug = analysisRecord.recordDebug();
        if (debug) {
            // $NON-NLS-1$
            analysisRecord.println("\n============================================================================");
            // $NON-NLS-1$
            analysisRecord.println("CONVERTING PLAN TREE TO PROCESS TREE");
        }
        // Convert plan tree nodes into process tree nodes
        RelationalNode processNode;
        try {
            processNode = convertPlan(planNode);
        } catch (TeiidProcessingException e) {
            if (e instanceof QueryPlannerException) {
                throw (QueryPlannerException) e;
            }
            throw new QueryPlannerException(e);
        }
        if (debug) {
            // $NON-NLS-1$
            analysisRecord.println("\nPROCESS PLAN = \n" + processNode);
            // $NON-NLS-1$
            analysisRecord.println("============================================================================");
        }
        RelationalPlan processPlan = new RelationalPlan(processNode);
        return processPlan;
    } finally {
        sharedCommands.clear();
    }
}
Also used : QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Example 8 with QueryPlannerException

use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.

the class PlanToProcessConverter method aliasCommand.

private Command aliasCommand(AccessNode aNode, Command command, Object modelID) throws TeiidComponentException, QueryPlannerException {
    try {
        command = (Command) command.clone();
        boolean aliasGroups = modelID != null && (CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
        boolean aliasColumns = modelID != null && (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
        AliasGenerator visitor = new AliasGenerator(aliasGroups, !aliasColumns);
        SourceHint sh = command.getSourceHint();
        if (sh != null && aliasGroups) {
            VDBMetaData vdb = context.getDQPWorkContext().getVDB();
            ModelMetaData model = vdb.getModel(aNode.getModelName());
            List<String> sourceNames = model.getSourceNames();
            SpecificHint sp = null;
            if (sourceNames.size() == 1) {
                sp = sh.getSpecificHint(sourceNames.get(0));
            }
            if (sh.isUseAliases() || (sp != null && sp.isUseAliases())) {
                visitor.setAliasMapping(context.getAliasMapping());
            }
        }
        List<Reference> references = ReferenceCollectorVisitor.getReferences(command);
        if (!references.isEmpty()) {
            Set<String> correleatedGroups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
            for (Reference ref : references) {
                if (ref.isCorrelated() && ref.getExpression().getGroupSymbol() != null) {
                    correleatedGroups.add(ref.getExpression().getGroupSymbol().getName());
                }
            }
            visitor.setCorrelationGroups(correleatedGroups);
        }
        command.acceptVisitor(visitor);
    } catch (QueryMetadataException err) {
        throw new TeiidComponentException(QueryPlugin.Event.TEIID30249, err);
    } catch (TeiidRuntimeException e) {
        if (e.getCause() instanceof QueryPlannerException) {
            throw (QueryPlannerException) e.getCause();
        }
        throw e;
    }
    return command;
}
Also used : Reference(org.teiid.query.sql.symbol.Reference) SpecificHint(org.teiid.query.sql.lang.SourceHint.SpecificHint) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) ModelMetaData(org.teiid.adminapi.impl.ModelMetaData) VDBMetaData(org.teiid.adminapi.impl.VDBMetaData) TeiidComponentException(org.teiid.core.TeiidComponentException) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 9 with QueryPlannerException

use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.

the class PlanToProcessConverter method setRoutingName.

private void setRoutingName(AccessNode accessNode, PlanNode node, Command command) throws QueryPlannerException, TeiidComponentException {
    // Look up connector binding name
    try {
        Object modelID = node.getProperty(NodeConstants.Info.MODEL_ID);
        if (modelID == null || modelID instanceof TempMetadataID) {
            if (command instanceof StoredProcedure) {
                modelID = ((StoredProcedure) command).getModelID();
            } else if (!(command instanceof Create || command instanceof Drop)) {
                Collection<GroupSymbol> groups = GroupCollectorVisitor.getGroups(command, true);
                GroupSymbol group = groups.iterator().next();
                modelID = metadata.getModelID(group.getMetadataID());
            }
        }
        String cbName = metadata.getFullName(modelID);
        accessNode.setModelName(cbName);
        accessNode.setModelId(modelID);
        accessNode.setConformedTo((Set<Object>) node.getProperty(Info.CONFORMED_SOURCES));
    } catch (QueryMetadataException e) {
        throw new QueryPlannerException(QueryPlugin.Event.TEIID30251, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30251));
    }
}
Also used : TempMetadataID(org.teiid.query.metadata.TempMetadataID) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 10 with QueryPlannerException

use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.

the class RelationalPlanner method planWith.

private void planWith(PlanNode plan, Command command) throws QueryPlannerException, QueryMetadataException, TeiidComponentException, QueryResolverException {
    if (this.withPlanningState.withList.isEmpty()) {
        return;
    }
    // TODO: merge this logic inline with the main rule execution.
    RuleStack stack = new RuleStack();
    stack.push(new RuleAssignOutputElements(false));
    if (hints.hasRowBasedSecurity) {
        stack.push(new RuleApplySecurity());
    }
    // use a temporary planner to run just the assign output elements
    RelationalPlanner planner = new RelationalPlanner();
    // we don't want to trigger the with processing for just projection
    planner.processWith = false;
    planner.initialize(command, idGenerator, metadata, capFinder, analysisRecord, context);
    planner.executeRules(stack, plan);
    // discover all of the usage
    List<Command> commands = CommandCollectorVisitor.getCommands(command, true);
    while (!commands.isEmpty()) {
        Command cmd = commands.remove(commands.size() - 1);
        commands.addAll(CommandCollectorVisitor.getCommands(cmd, true));
        try {
            PlanNode temp = planner.generatePlan((Command) cmd.clone());
            stack.push(new RuleAssignOutputElements(false));
            planner.executeRules(stack, temp);
        } catch (TeiidProcessingException e) {
            throw new QueryPlannerException(e);
        }
    }
    // plan and minimize projection
    for (WithQueryCommand with : this.withPlanningState.withList.values()) {
        QueryCommand subCommand = with.getCommand();
        TempMetadataID tid = (TempMetadataID) with.getGroupSymbol().getMetadataID();
        if (tid.getTableData().getModel() != TempMetadataAdapter.TEMP_MODEL) {
            tid.getTableData().setModel(null);
        }
        List<TempMetadataID> elements = tid.getElements();
        List<Integer> toRemove = new ArrayList<Integer>();
        for (int i = elements.size() - 1; i >= 0; i--) {
            TempMetadataID elem = elements.get(i);
            if (!elem.isAccessed()) {
                toRemove.add(i);
            }
        }
        // the definition of the with clause consistent
        if (!toRemove.isEmpty()) {
            if (with.isRecursive()) {
                SetQuery setQuery = (SetQuery) subCommand;
                setQuery.setLeftQuery(removeUnusedProjection(with, setQuery.getLeftQuery(), elements, toRemove));
                setQuery.setRightQuery(removeUnusedProjection(with, setQuery.getRightQuery(), elements, toRemove));
            } else {
                subCommand = removeUnusedProjection(with, subCommand, elements, toRemove);
                with.setCommand(subCommand);
            }
        }
        if (with.isRecursive()) {
            SetQuery setQuery = (SetQuery) subCommand;
            QueryCommand qc = setQuery.getLeftQuery();
            final RelationalPlan subPlan = optimize(qc);
            qc.setProcessorPlan(subPlan);
            AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(subPlan);
            Object modelID = null;
            QueryCommand withCommand = null;
            if (aNode != null) {
                modelID = CriteriaCapabilityValidatorVisitor.validateCommandPushdown(null, metadata, capFinder, aNode, false);
                if (modelID != null) {
                    if (with.getGroupSymbol().getModelMetadataId() != null || !CapabilitiesUtil.supports(Capability.RECURSIVE_COMMON_TABLE_EXPRESSIONS, modelID, metadata, capFinder) || with.isMaterialize()) {
                        modelID = null;
                    } else {
                        withCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(aNode);
                        if (withCommand != null) {
                            // provisionally set the source
                            ((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(modelID);
                        }
                    }
                }
            }
            // now that we possibly have a model id, plan the recursive part
            QueryCommand qc1 = setQuery.getRightQuery();
            RelationalPlan subPlan1 = optimize((Command) qc1.clone());
            qc1.setProcessorPlan(subPlan1);
            if (!isPushdownValid(with, setQuery, modelID, withCommand, subPlan1) && withCommand != null) {
                // reset the source to null and replan
                ((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(null);
                subPlan1 = optimize(qc1);
                qc1.setProcessorPlan(subPlan1);
            }
            continue;
        }
        RelationalPlan subPlan = optimize(subCommand);
        subCommand.setProcessorPlan(subPlan);
        RelationalPlan procPlan = subPlan;
        RelationalNode root = procPlan.getRootNode();
        Number planCardinality = root.getEstimateNodeCardinality();
        if (planCardinality != null) {
            ((TempMetadataID) with.getGroupSymbol().getMetadataID()).setCardinality(planCardinality.intValue());
        }
        AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(procPlan);
        if (aNode == null) {
            continue;
        }
        Object modelID = CriteriaCapabilityValidatorVisitor.validateCommandPushdown(null, metadata, capFinder, aNode, false);
        QueryCommand withCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(aNode);
        if (modelID == null || withCommand == null) {
            continue;
        }
        if (with.getGroupSymbol().getModelMetadataId() != null || !CapabilitiesUtil.supports(Capability.COMMON_TABLE_EXPRESSIONS, modelID, metadata, capFinder) || with.isMaterialize()) {
            continue;
        }
        WithQueryCommand wqc = new WithQueryCommand(with.getGroupSymbol(), with.getColumns(), withCommand);
        wqc.setNoInline(with.isNoInline());
        ((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(modelID);
        this.withPlanningState.pushdownWith.put(with.getGroupSymbol().getName(), wqc);
    }
}
Also used : TempMetadataID(org.teiid.query.metadata.TempMetadataID) RelationalPlan(org.teiid.query.processor.relational.RelationalPlan) TeiidProcessingException(org.teiid.core.TeiidProcessingException) SubqueryAwareRelationalNode(org.teiid.query.processor.relational.SubqueryAwareRelationalNode) RelationalNode(org.teiid.query.processor.relational.RelationalNode) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) LanguageObject(org.teiid.query.sql.LanguageObject) AccessNode(org.teiid.query.processor.relational.AccessNode) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Aggregations

QueryPlannerException (org.teiid.api.exception.query.QueryPlannerException)27 TeiidProcessingException (org.teiid.core.TeiidProcessingException)11 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)11 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)11 ProcessorPlan (org.teiid.query.processor.ProcessorPlan)8 Expression (org.teiid.query.sql.symbol.Expression)8 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)8 SymbolMap (org.teiid.query.sql.util.SymbolMap)8 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)6 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)5 TempMetadataID (org.teiid.query.metadata.TempMetadataID)5 CreateProcedureCommand (org.teiid.query.sql.proc.CreateProcedureCommand)5 ArrayList (java.util.ArrayList)4 TeiidComponentException (org.teiid.core.TeiidComponentException)4 Criteria (org.teiid.query.sql.lang.Criteria)4 HashSet (java.util.HashSet)3 List (java.util.List)3 AnalysisRecord (org.teiid.query.analysis.AnalysisRecord)3 RelationalPlan (org.teiid.query.processor.relational.RelationalPlan)3 HashMap (java.util.HashMap)2