Search in sources :

Example 51 with Criteria

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

the class FrameUtil method convertNode.

// If newGroup == null, this will be performing a straight symbol swap - that is,
// an oldGroup is undergoing a name change and that is the only difference in the
// symbols.  In that case, some additional work can be done because we can assume
// that an oldElement isn't being replaced by an expression using elements from
// multiple new groups.
static void convertNode(PlanNode node, GroupSymbol oldGroup, Set<GroupSymbol> newGroups, Map symbolMap, QueryMetadataInterface metadata, boolean rewrite) throws QueryPlannerException {
    if (node.getType() == NodeConstants.Types.GROUP) {
        correctSymbolMap(symbolMap, node);
    }
    // Convert expressions from correlated subquery references;
    List<SymbolMap> refMaps = node.getAllReferences();
    LinkedList<Expression> correlatedExpression = new LinkedList<Expression>();
    for (SymbolMap refs : refMaps) {
        for (Map.Entry<ElementSymbol, Expression> ref : refs.asUpdatableMap().entrySet()) {
            Expression expr = ref.getValue();
            Expression convertedExpr = convertExpression(expr, symbolMap);
            ref.setValue(convertedExpr);
            correlatedExpression.add(convertedExpr);
        }
    }
    // Update groups for current node
    Set<GroupSymbol> groups = node.getGroups();
    boolean hasOld = groups.remove(oldGroup);
    int type = node.getType();
    boolean singleMapping = newGroups != null && newGroups.size() == 1;
    if (singleMapping) {
        if (!hasOld) {
            return;
        }
        groups.addAll(newGroups);
    } else if ((type & (NodeConstants.Types.ACCESS | NodeConstants.Types.JOIN | NodeConstants.Types.SOURCE)) == type) {
        if (newGroups != null) {
            groups.addAll(newGroups);
        }
    } else {
        groups.clear();
    }
    groups.addAll(GroupsUsedByElementsVisitor.getGroups(correlatedExpression));
    if (type == NodeConstants.Types.SELECT) {
        Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
        crit = convertCriteria(crit, symbolMap, metadata, rewrite);
        node.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
        if (!singleMapping) {
            GroupsUsedByElementsVisitor.getGroups(crit, groups);
        }
    } else if (type == NodeConstants.Types.PROJECT) {
        List<Expression> projectedSymbols = (List<Expression>) node.getProperty(NodeConstants.Info.PROJECT_COLS);
        Select select = new Select(projectedSymbols);
        ExpressionMappingVisitor.mapExpressions(select, symbolMap);
        if (rewrite) {
            for (LanguageObject expr : select.getSymbols()) {
                rewriteSingleElementSymbol(metadata, (Expression) expr);
            }
        }
        node.setProperty(NodeConstants.Info.PROJECT_COLS, select.getSymbols());
        if (!singleMapping) {
            GroupsUsedByElementsVisitor.getGroups(select, groups);
        }
    } else if (type == NodeConstants.Types.JOIN) {
        // Convert join criteria property
        List<Criteria> joinCrits = (List<Criteria>) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
        if (joinCrits != null && !joinCrits.isEmpty()) {
            Criteria crit = new CompoundCriteria(joinCrits);
            crit = convertCriteria(crit, symbolMap, metadata, rewrite);
            if (crit instanceof CompoundCriteria && ((CompoundCriteria) crit).getOperator() == CompoundCriteria.AND) {
                node.setProperty(NodeConstants.Info.JOIN_CRITERIA, ((CompoundCriteria) crit).getCriteria());
            } else {
                joinCrits = new ArrayList<Criteria>();
                joinCrits.add(crit);
                node.setProperty(NodeConstants.Info.JOIN_CRITERIA, joinCrits);
            }
        }
        convertAccessPatterns(symbolMap, node);
    } else if (type == NodeConstants.Types.SORT) {
        OrderBy orderBy = (OrderBy) node.getProperty(NodeConstants.Info.SORT_ORDER);
        ExpressionMappingVisitor.mapExpressions(orderBy, symbolMap);
        if (rewrite) {
            for (OrderByItem item : orderBy.getOrderByItems()) {
                rewriteSingleElementSymbol(metadata, item.getSymbol());
            }
        }
        if (!singleMapping) {
            GroupsUsedByElementsVisitor.getGroups(orderBy, groups);
        }
    } else if (type == NodeConstants.Types.GROUP) {
        List<Expression> groupCols = (List<Expression>) node.getProperty(NodeConstants.Info.GROUP_COLS);
        if (groupCols != null) {
            GroupBy groupBy = new GroupBy(groupCols);
            ExpressionMappingVisitor.mapExpressions(groupBy, symbolMap);
            node.setProperty(NodeConstants.Info.GROUP_COLS, groupBy.getSymbols());
            if (!singleMapping) {
                GroupsUsedByElementsVisitor.getGroups(groupBy, groups);
            }
        }
        if (!singleMapping) {
            // add back the anon group
            SymbolMap property = (SymbolMap) node.getProperty(Info.SYMBOL_MAP);
            if (!property.asMap().isEmpty()) {
                groups.add(property.asMap().keySet().iterator().next().getGroupSymbol());
            }
        }
    } else if (type == NodeConstants.Types.SOURCE || type == NodeConstants.Types.ACCESS) {
        convertAccessPatterns(symbolMap, node);
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) OrderBy(org.teiid.query.sql.lang.OrderBy) GroupBy(org.teiid.query.sql.lang.GroupBy) SymbolMap(org.teiid.query.sql.util.SymbolMap) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) Criteria(org.teiid.query.sql.lang.Criteria) OrderByItem(org.teiid.query.sql.lang.OrderByItem) Expression(org.teiid.query.sql.symbol.Expression) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) Select(org.teiid.query.sql.lang.Select) SymbolMap(org.teiid.query.sql.util.SymbolMap) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 52 with Criteria

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

the class JoinRegion method getJoinCriteriaForGroups.

// TODO: this should be better than a linear search
protected List<PlanNode> getJoinCriteriaForGroups(Set<GroupSymbol> groups, Collection<PlanNode> nodes) {
    List<PlanNode> result = new LinkedList<PlanNode>();
    for (PlanNode critNode : nodes) {
        if (groups.containsAll(critNode.getGroups())) {
            Criteria crit = (Criteria) critNode.getProperty(Info.SELECT_CRITERIA);
            if (crit instanceof CompareCriteria && ((CompareCriteria) crit).isOptional()) {
                continue;
            }
            result.add(critNode);
        }
    }
    return result;
}
Also used : PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) CompoundCriteria(org.teiid.query.sql.lang.CompoundCriteria) Criteria(org.teiid.query.sql.lang.Criteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria) CompareCriteria(org.teiid.query.sql.lang.CompareCriteria)

Example 53 with Criteria

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

the class RuleAccessPatternValidation method validateAccessPatterns.

/**
 * @param node
 * @throws QueryPlannerException
 */
private void validateAccessPatterns(PlanNode node) throws QueryPlannerException {
    if (!node.hasCollectionProperty(NodeConstants.Info.ACCESS_PATTERNS)) {
        return;
    }
    Criteria criteria = null;
    if (node.hasProperty(NodeConstants.Info.ATOMIC_REQUEST)) {
        Object req = node.getProperty(NodeConstants.Info.ATOMIC_REQUEST);
        if (req instanceof Insert) {
            return;
        }
        if (req instanceof Delete) {
            criteria = ((Delete) req).getCriteria();
        } else if (req instanceof Update) {
            criteria = ((Update) req).getCriteria();
        }
    }
    List accessPatterns = (List) node.getProperty(NodeConstants.Info.ACCESS_PATTERNS);
    if (criteria != null) {
        for (Criteria crit : Criteria.separateCriteriaByAnd(criteria)) {
            Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(crit, true);
            if (RulePushSelectCriteria.satisfyAccessPatterns(accessPatterns, elements)) {
                return;
            }
        }
    }
    Object groups = node.getGroups();
    throw new QueryPlannerException(QueryPlugin.Event.TEIID30278, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30278, new Object[] { groups, accessPatterns }));
}
Also used : Delete(org.teiid.query.sql.lang.Delete) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) List(java.util.List) Criteria(org.teiid.query.sql.lang.Criteria) Insert(org.teiid.query.sql.lang.Insert) Update(org.teiid.query.sql.lang.Update) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 54 with Criteria

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

the class RuleApplySecurity method execute.

@Override
public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capabilitiesFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) throws QueryPlannerException, QueryMetadataException, TeiidComponentException {
    try {
        for (PlanNode sourceNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SOURCE)) {
            GroupSymbol group = sourceNode.getGroups().iterator().next();
            if (!RowBasedSecurityHelper.applyRowSecurity(metadata, group, context)) {
                continue;
            }
            List<ElementSymbol> cols = null;
            Command command = (Command) sourceNode.getProperty(Info.VIRTUAL_COMMAND);
            if (group.isProcedure()) {
                if (command == null) {
                    // proc relational, will instead apply at the proc level
                    continue;
                }
                if (cols == null) {
                    cols = (List) command.getProjectedSymbols();
                }
            } else if (command != null && !command.returnsResultSet()) {
                // should be handled in the planner
                continue;
            }
            if (cols == null) {
                cols = ResolverUtil.resolveElementsInGroup(group, metadata);
            }
            // apply masks first
            List<? extends Expression> masked = ColumnMaskingHelper.maskColumns(cols, group, metadata, context);
            Map<ElementSymbol, Expression> mapping = null;
            // TODO: we don't actually allow window function masks yet becuase they won't pass
            // validation.  but if we do, we need to check for them here
            List<WindowFunction> windowFunctions = new ArrayList<WindowFunction>(2);
            for (int i = 0; i < masked.size(); i++) {
                Expression maskedCol = masked.get(i);
                AggregateSymbolCollectorVisitor.getAggregates(maskedCol, null, null, null, windowFunctions, null);
                if (maskedCol.equals(cols.get(i))) {
                    continue;
                }
                if (mapping == null) {
                    mapping = new HashMap<ElementSymbol, Expression>();
                }
                mapping.put(cols.get(i), maskedCol);
            }
            PlanNode parentJoin = NodeEditor.findParent(sourceNode.getParent(), NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE);
            if (mapping != null) {
                // some element symbol has been replaced
                PlanNode project = null;
                if (group.isProcedure()) {
                    project = NodeEditor.findParent(sourceNode, NodeConstants.Types.PROJECT);
                    project.setProperty(NodeConstants.Info.PROJECT_COLS, masked);
                }
                if (windowFunctions.isEmpty() && RuleMergeVirtual.checkProjectedSymbols(group, parentJoin, metadata, masked, Collections.singleton(group), true)) {
                    if (!group.isProcedure()) {
                        // just upwardly project - TODO: we could also handle some subquery simple projection situations here
                        FrameUtil.convertFrame(sourceNode.getParent(), group, Collections.singleton(group), mapping, metadata);
                    }
                } else {
                    if (!group.isProcedure()) {
                        project = RelationalPlanner.createProjectNode(masked);
                    }
                    rules.getPlanner().planSubqueries(sourceNode.getGroups(), project, project.getSubqueryContainers(), true);
                    project.addGroups(GroupsUsedByElementsVisitor.getGroups(project.getCorrelatedReferenceElements()));
                    if (!group.isProcedure()) {
                        // we need to insert a view to give a single place to evaluate the subqueries
                        PlanNode root = sourceNode;
                        if (sourceNode.getParent().getType() == NodeConstants.Types.ACCESS) {
                            root = sourceNode.getParent();
                        }
                        root.addAsParent(project);
                        addView(metadata, context, group, cols, masked, project);
                        parentJoin = null;
                    }
                }
                if (!windowFunctions.isEmpty() && project != null) {
                    project.setProperty(Info.HAS_WINDOW_FUNCTIONS, true);
                }
            }
            // logically filters are applied below masking
            Criteria filter = RowBasedSecurityHelper.getRowBasedFilters(metadata, group, context, false);
            if (filter == null) {
                continue;
            }
            List<Criteria> crits = Criteria.separateCriteriaByAnd(filter);
            PlanNode root = sourceNode;
            if (sourceNode.getParent().getType() == NodeConstants.Types.ACCESS) {
                root = sourceNode.getParent();
            }
            PlanNode parent = null;
            for (Criteria crit : crits) {
                PlanNode critNode = RelationalPlanner.createSelectNode(crit, false);
                if (parent == null) {
                    parent = critNode;
                }
                rules.getPlanner().planSubqueries(sourceNode.getGroups(), critNode, critNode.getSubqueryContainers(), true);
                critNode.addGroups(GroupsUsedByElementsVisitor.getGroups(critNode.getCorrelatedReferenceElements()));
                root.addAsParent(critNode);
            }
            if (!RuleMergeVirtual.checkJoinCriteria(parent, group, parentJoin)) {
                PlanNode project = RelationalPlanner.createProjectNode(cols);
                parent.addAsParent(project);
                // a view is needed to keep the logical placement of the criteria
                addView(metadata, context, group, cols, cols, project);
            }
        }
    } catch (TeiidProcessingException e) {
        throw new QueryPlannerException(e);
    }
    return plan;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) ArrayList(java.util.ArrayList) Criteria(org.teiid.query.sql.lang.Criteria) TeiidProcessingException(org.teiid.core.TeiidProcessingException) WindowFunction(org.teiid.query.sql.symbol.WindowFunction) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) Command(org.teiid.query.sql.lang.Command) Expression(org.teiid.query.sql.symbol.Expression) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 55 with Criteria

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

the class QueryParser method parseCriteria.

/**
 * Takes a SQL string representing an SQL criteria (i.e. just the WHERE
 * clause) and returns the object representation.
 * @param sql SQL criteria (WHERE clause) string
 * @return Criteria SQL object representation
 * @throws QueryParserException if parsing fails
 * @throws IllegalArgumentException if sql is null
 */
public Criteria parseCriteria(String sql) throws QueryParserException {
    if (sql == null) {
        // $NON-NLS-1$
        throw new IllegalArgumentException(QueryPlugin.Util.getString("QueryParser.nullSqlCrit"));
    }
    ParseInfo dummyInfo = new ParseInfo();
    Criteria result = null;
    try {
        result = getSqlParser(sql).criteria(dummyInfo);
    } catch (ParseException pe) {
        throw convertParserException(pe);
    } finally {
        tm.reinit();
    }
    return result;
}
Also used : Criteria(org.teiid.query.sql.lang.Criteria)

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