Search in sources :

Example 16 with LanguageObject

use of org.teiid.query.sql.LanguageObject 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)

Example 17 with LanguageObject

use of org.teiid.query.sql.LanguageObject in project teiid by teiid.

the class AuthorizationValidationVisitor method validateEntitlements.

/**
 * Check that the user is entitled to access all data elements in the command.
 *
 * @param symbols The collection of <code>Symbol</code>s affected by these actions.
 * @param actionCode The actions to validate for
 * @param auditContext The {@link AuthorizationService} to use when resource auditing is done.
 */
protected void validateEntitlements(Collection<? extends LanguageObject> symbols, DataPolicy.PermissionType actionCode, Context auditContext) {
    Map<String, LanguageObject> nameToSymbolMap = new LinkedHashMap<String, LanguageObject>();
    for (LanguageObject symbol : symbols) {
        try {
            Object metadataID = null;
            if (symbol instanceof ElementSymbol) {
                metadataID = ((ElementSymbol) symbol).getMetadataID();
                if (metadataID instanceof MultiSourceElement || metadataID instanceof TempMetadataID) {
                    continue;
                }
            } else if (symbol instanceof GroupSymbol) {
                GroupSymbol group = (GroupSymbol) symbol;
                metadataID = group.getMetadataID();
                if (metadataID instanceof TempMetadataID) {
                    if (group.isProcedure()) {
                        Map<String, LanguageObject> procMap = new LinkedHashMap<String, LanguageObject>();
                        addToNameMap(((TempMetadataID) metadataID).getOriginalMetadataID(), symbol, procMap, getMetadata());
                        validateEntitlements(PermissionType.EXECUTE, auditContext, procMap);
                    } else if (group.isTempTable() && group.isImplicitTempGroupSymbol()) {
                        validateTemp(actionCode, group.getNonCorrelationName(), false, group, auditContext);
                    }
                    continue;
                }
            }
            addToNameMap(metadataID, symbol, nameToSymbolMap, getMetadata());
        } catch (QueryMetadataException e) {
            handleException(e);
        } catch (TeiidComponentException e) {
            handleException(e);
        }
    }
    validateEntitlements(actionCode, auditContext, nameToSymbolMap);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) TempMetadataID(org.teiid.query.metadata.TempMetadataID) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) LanguageObject(org.teiid.query.sql.LanguageObject) TeiidComponentException(org.teiid.core.TeiidComponentException) LanguageObject(org.teiid.query.sql.LanguageObject) MultiSourceElement(org.teiid.dqp.internal.process.multisource.MultiSourceElement)

Example 18 with LanguageObject

use of org.teiid.query.sql.LanguageObject in project teiid by teiid.

the class AnalysisRecord method addLanaguageObjects.

public static void addLanaguageObjects(PlanNode node, String key, Collection<? extends LanguageObject> objects) {
    List<String> values = new ArrayList<String>();
    int index = 0;
    for (LanguageObject languageObject : objects) {
        values.add(languageObject.toString());
        List<SubqueryContainer<?>> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(languageObject);
        for (ListIterator<SubqueryContainer<?>> iterator = subqueries.listIterator(); iterator.hasNext(); ) {
            SubqueryContainer<?> subqueryContainer = iterator.next();
            // $NON-NLS-1$
            node.addProperty(key + " Subplan " + index++, subqueryContainer.getCommand().getProcessorPlan().getDescriptionProperties());
        }
    }
    node.addProperty(key, values);
}
Also used : SubqueryContainer(org.teiid.query.sql.lang.SubqueryContainer) ArrayList(java.util.ArrayList) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 19 with LanguageObject

use of org.teiid.query.sql.LanguageObject in project teiid by teiid.

the class RulePlanProcedures method findInputNodes.

private void findInputNodes(final HashSet<ElementSymbol> inputs, PlanNode critNode, final List<Criteria> conjuncts, final Set<ElementSymbol> params) {
    while (critNode.getType() == NodeConstants.Types.SELECT) {
        final PlanNode currentNode = critNode;
        final Criteria crit = (Criteria) currentNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
        critNode = currentNode.getParent();
        if (!currentNode.getGroups().isEmpty()) {
            continue;
        }
        LanguageVisitor visitor = new LanguageVisitor() {

            public void visit(CompareCriteria compCrit) {
                if (compCrit.getOperator() == CompareCriteria.EQ && checkForInput(compCrit.getLeftExpression()) && !checkForAnyInput(compCrit.getRightExpression())) {
                    addInputNode((Reference) compCrit.getLeftExpression());
                }
            }

            private void addInputNode(Reference param) {
                params.add(param.getExpression());
                conjuncts.add(crit);
                NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
            }

            public void visit(IsNullCriteria isNull) {
                if (!isNull.isNegated() && checkForInput(isNull.getExpression())) {
                    addInputNode((Reference) isNull.getExpression());
                }
            }

            public void visit(SetCriteria obj) {
                if (!obj.isNegated() && checkForInput(obj.getExpression()) && !checkForAnyInput(obj.getValues())) {
                    addInputNode((Reference) obj.getExpression());
                }
            }

            public void visit(DependentSetCriteria obj) {
                if (obj.isNegated()) {
                    // just a sanity check
                    return;
                }
                if (obj.hasMultipleAttributes()) {
                    for (AttributeComparison comp : obj.getAttributes()) {
                        if (!checkForInput(comp.dep)) {
                            return;
                        }
                    }
                    for (AttributeComparison comp : obj.getAttributes()) {
                        params.add(((Reference) comp.dep).getExpression());
                    }
                    conjuncts.add(crit);
                    NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
                } else if (checkForInput(obj.getExpression())) {
                    addInputNode((Reference) obj.getExpression());
                }
            }

            boolean checkForInput(Expression expr) {
                if (!(expr instanceof Reference)) {
                    return false;
                }
                // if the expr is a function containing a reference should give a warning
                Reference ref = (Reference) expr;
                return inputs.contains(ref.getExpression());
            }

            boolean checkForAnyInput(LanguageObject expr) {
                for (Reference ref : ReferenceCollectorVisitor.getReferences(expr)) {
                    if (checkForInput(ref)) {
                        return true;
                    }
                }
                return false;
            }

            boolean checkForAnyInput(Collection<Expression> expressions) {
                for (Expression expr : expressions) {
                    if (checkForAnyInput(expr)) {
                        return true;
                    }
                }
                return false;
            }
        };
        for (Criteria conjunct : Criteria.separateCriteriaByAnd(crit)) {
            conjunct.acceptVisitor(visitor);
        }
    }
}
Also used : LanguageVisitor(org.teiid.query.sql.LanguageVisitor) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) Expression(org.teiid.query.sql.symbol.Expression) Reference(org.teiid.query.sql.symbol.Reference) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) SetCriteria(org.teiid.query.sql.lang.SetCriteria) Collection(java.util.Collection) DependentSetCriteria(org.teiid.query.sql.lang.DependentSetCriteria) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) SetCriteria(org.teiid.query.sql.lang.SetCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) AttributeComparison(org.teiid.query.sql.lang.DependentSetCriteria.AttributeComparison) LanguageObject(org.teiid.query.sql.LanguageObject) IsNullCriteria(org.teiid.query.sql.lang.IsNullCriteria)

Example 20 with LanguageObject

use of org.teiid.query.sql.LanguageObject in project teiid by teiid.

the class RelationalPlanner method assignWithClause.

private void assignWithClause(RelationalNode node, LinkedHashMap<String, WithQueryCommand> pushdownWith, boolean repeated) throws QueryPlannerException, TeiidComponentException {
    List<SubqueryContainer<?>> subCommands = new ArrayList<SubqueryContainer<?>>();
    if (node instanceof SubqueryAwareRelationalNode) {
        for (LanguageObject lo : ((SubqueryAwareRelationalNode) node).getObjects()) {
            ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(lo, subCommands);
            if (!subCommands.isEmpty()) {
                for (SubqueryContainer<?> subquery : subCommands) {
                    if (subquery.getCommand().getProcessorPlan() instanceof RelationalPlan) {
                        assignWithClause(((RelationalPlan) subquery.getCommand().getProcessorPlan()).getRootNode(), pushdownWith, repeated | (subquery.getCommand().getCorrelatedReferences() != null && !subquery.getCommand().getCorrelatedReferences().asMap().isEmpty()));
                    }
                }
                subCommands.clear();
            }
        }
    }
    if (node instanceof PlanExecutionNode) {
        // need to check for nested relational plans.  these are created by things such as the semi-join optimization in rulemergevirtual
        ProcessorPlan plan = ((PlanExecutionNode) node).getProcessorPlan();
        if (plan instanceof RelationalPlan) {
            // other types of plans will be contained under non-relational plans, which would be out of scope for the parent with
            node = ((RelationalPlan) plan).getRootNode();
        }
    }
    if (node instanceof AccessNode) {
        AccessNode accessNode = (AccessNode) node;
        Map<GroupSymbol, RelationalPlan> subplans = accessNode.getSubPlans();
        if (subplans != null) {
            for (RelationalPlan subplan : subplans.values()) {
                assignWithClause(subplan.getRootNode(), pushdownWith, false);
            }
        }
        Command command = accessNode.getCommand();
        if (command instanceof Insert && ((Insert) command).getQueryExpression() != null) {
            command = ((Insert) command).getQueryExpression();
        }
        if (command instanceof QueryCommand) {
            if (this.withGroups == null) {
                this.withGroups = new TreeSet<GroupSymbol>(nonCorrelatedComparator);
            } else {
                this.withGroups.clear();
            }
            GroupCollectorVisitor.getGroupsIgnoreInlineViewsAndEvaluatableSubqueries(command, this.withGroups);
            List<WithQueryCommand> with = new ArrayList<WithQueryCommand>();
            discoverWith(pushdownWith, command, with, new ArrayList<GroupSymbol>(this.withGroups));
            if (!with.isEmpty()) {
                List<WithQueryCommand> pushed = new ArrayList<WithQueryCommand>(with);
                final Map<GroupSymbol, Integer> order = new HashMap<GroupSymbol, Integer>();
                for (WithQueryCommand withQueryCommand : pushdownWith.values()) {
                    order.put(withQueryCommand.getGroupSymbol(), order.size());
                }
                Collections.sort(with, new Comparator<WithQueryCommand>() {

                    @Override
                    public int compare(WithQueryCommand o1, WithQueryCommand o2) {
                        return order.get(o1.getGroupSymbol()).compareTo(order.get(o2.getGroupSymbol()));
                    }
                });
                // pull up the with from the subqueries
                for (int i = 0; i < with.size(); i++) {
                    WithQueryCommand wqc = with.get(i);
                    List<WithQueryCommand> with2 = wqc.getCommand().getWith();
                    if (with2 != null) {
                        with.addAll(i, with2);
                        i += with2.size();
                        wqc.getCommand().setWith(null);
                    }
                }
                QueryCommand query = (QueryCommand) command;
                List<SubqueryContainer<?>> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(query);
                this.withGroups.clear();
                for (WithQueryCommand wqc : with) {
                    withGroups.add(wqc.getGroupSymbol());
                }
                pullupWith(with, subqueries, withGroups);
                if (query.getWith() != null) {
                    // we need to accumulate as a with clause could have been used at a lower scope
                    query.getWith().addAll(with);
                } else {
                    query.setWith(with);
                }
                for (WithQueryCommand wqc : pushed) {
                    Object o = this.withPlanningState.pushdownState.get(wqc.getGroupSymbol().getName());
                    if (o == null) {
                        if (!repeated) {
                            if (accessNode.info != null) {
                                o = accessNode.info.id;
                            } else {
                                o = Boolean.FALSE;
                            }
                        } else {
                            o = Boolean.TRUE;
                        }
                    } else if (o instanceof Integer) {
                        // check for shared
                        if (accessNode.info == null || !o.equals(accessNode.info.id)) {
                            o = Boolean.TRUE;
                        }
                    } else {
                        o = Boolean.TRUE;
                    }
                    this.withPlanningState.pushdownState.put(wqc.getGroupSymbol().getName(), o);
                }
                // TODO: this should be based upon whether any of the need evaluated
                accessNode.setShouldEvaluateExpressions(true);
            }
        }
    }
    // Recurse through children
    RelationalNode[] children = node.getChildren();
    for (int i = 0; i < node.getChildCount(); i++) {
        assignWithClause(children[i], pushdownWith, repeated);
    }
}
Also used : RelationalPlan(org.teiid.query.processor.relational.RelationalPlan) PlanExecutionNode(org.teiid.query.processor.relational.PlanExecutionNode) AccessNode(org.teiid.query.processor.relational.AccessNode) SubqueryAwareRelationalNode(org.teiid.query.processor.relational.SubqueryAwareRelationalNode) SubqueryAwareRelationalNode(org.teiid.query.processor.relational.SubqueryAwareRelationalNode) RelationalNode(org.teiid.query.processor.relational.RelationalNode) CreateProcedureCommand(org.teiid.query.sql.proc.CreateProcedureCommand) LanguageObject(org.teiid.query.sql.LanguageObject) ProcessorPlan(org.teiid.query.processor.ProcessorPlan) LanguageObject(org.teiid.query.sql.LanguageObject)

Aggregations

LanguageObject (org.teiid.query.sql.LanguageObject)28 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)8 TeiidComponentException (org.teiid.core.TeiidComponentException)7 ArrayList (java.util.ArrayList)5 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)5 HashSet (java.util.HashSet)3 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)3 Command (org.teiid.query.sql.lang.Command)3 Criteria (org.teiid.query.sql.lang.Criteria)3 Select (org.teiid.query.sql.lang.Select)3 Expression (org.teiid.query.sql.symbol.Expression)3 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 Test (org.junit.Test)2 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)2 MultiSourceElement (org.teiid.dqp.internal.process.multisource.MultiSourceElement)2 TempMetadataID (org.teiid.query.metadata.TempMetadataID)2 PlanNode (org.teiid.query.optimizer.relational.plantree.PlanNode)2 CompareCriteria (org.teiid.query.sql.lang.CompareCriteria)2