Search in sources :

Example 21 with LanguageObject

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

the class CriteriaCapabilityValidatorVisitor method canPushLanguageObject.

public static boolean canPushLanguageObject(LanguageObject obj, Object modelID, final QueryMetadataInterface metadata, CapabilitiesFinder capFinder, AnalysisRecord analysisRecord, boolean isJoin, boolean isSelectClause, final boolean multiValuedReferences) throws QueryMetadataException, TeiidComponentException {
    if (obj == null) {
        return true;
    }
    if (modelID == null || metadata.isVirtualModel(modelID)) {
        // Couldn't determine model ID, so give up
        return false;
    }
    String modelName = metadata.getFullName(modelID);
    SourceCapabilities caps = capFinder.findCapabilities(modelName);
    if (caps == null) {
        // this doesn't seem right, but tests were expecting it...
        return true;
    }
    CriteriaCapabilityValidatorVisitor visitor = new CriteriaCapabilityValidatorVisitor(modelID, metadata, capFinder, caps);
    visitor.setCheckEvaluation(!multiValuedReferences);
    visitor.analysisRecord = analysisRecord;
    visitor.isJoin = isJoin;
    visitor.isSelectClause = isSelectClause;
    // we use an array to represent multiple comparision attributes,
    // but we don't want that to inhibit pushdown as we'll account for that later
    // in criteria processing
    final EvaluatableVisitor ev = new EvaluatableVisitor(modelID, metadata, capFinder);
    PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, PreOrPostOrderNavigator.POST_ORDER, false) {

        @Override
        public void visit(DependentSetCriteria obj1) {
            if (obj1.hasMultipleAttributes()) {
                Array array = (Array) obj1.getExpression();
                visitNodes(array.getExpressions());
                super.postVisitVisitor(obj1);
            } else {
                super.visit(obj1);
            }
        }

        @Override
        protected void visitNode(LanguageObject obj) {
            if (obj == null) {
                return;
            }
            Determinism d = ev.getDeterminismLevel();
            boolean pushDown = ev.requiresEvaluation(EvaluationLevel.PUSH_DOWN);
            // decend with clean state, then restore
            ev.reset();
            super.visitNode(obj);
            ev.setDeterminismLevel(d);
            if (pushDown) {
                ev.evaluationNotPossible(EvaluationLevel.PUSH_DOWN);
            }
        }

        @Override
        protected void visitVisitor(LanguageObject obj) {
            if (obj == null) {
                return;
            }
            if (!ev.requiresEvaluation(EvaluationLevel.PUSH_DOWN) && ev.getDeterminismLevel() != Determinism.NONDETERMINISTIC) {
                if (obj instanceof ElementSymbol) {
                    ElementSymbol es = (ElementSymbol) obj;
                    if (es.getMetadataID() != null) {
                        try {
                            if (metadata.isMultiSourceElement(es.getMetadataID())) {
                                // no need to visit
                                return;
                            }
                        } catch (QueryMetadataException e) {
                        } catch (TeiidComponentException e) {
                        }
                    }
                }
                obj.acceptVisitor(ev);
                if (!multiValuedReferences && obj instanceof Expression) {
                    if (obj instanceof Function) {
                        if (!(obj instanceof AggregateSymbol)) {
                            Function f = (Function) obj;
                            if (f.getFunctionDescriptor().getPushdown() != PushDown.MUST_PUSHDOWN && f.getFunctionDescriptor().getDeterministic() != Determinism.NONDETERMINISTIC) {
                                // don't need to consider
                                return;
                            }
                        }
                    } else if (obj instanceof Criteria && !(obj instanceof SubqueryContainer) && !(obj instanceof DependentSetCriteria)) {
                        // don't need to consider
                        return;
                    }
                }
            }
            super.visitVisitor(obj);
        }
    };
    obj.acceptVisitor(nav);
    if (visitor.getException() != null) {
        throw visitor.getException();
    }
    return visitor.isValid();
}
Also used : Determinism(org.teiid.metadata.FunctionMethod.Determinism) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) EvaluatableVisitor(org.teiid.query.sql.visitor.EvaluatableVisitor) PreOrPostOrderNavigator(org.teiid.query.sql.navigator.PreOrPostOrderNavigator) TeiidComponentException(org.teiid.core.TeiidComponentException) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 22 with LanguageObject

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

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

the class ResolverVisitor method resolveCompareCriteria.

void resolveCompareCriteria(BinaryComparison ccrit, LanguageObject surrounding) throws QueryResolverException {
    Expression leftExpression = ccrit.getLeftExpression();
    Expression rightExpression = ccrit.getRightExpression();
    // Check typing between expressions
    setDesiredType(leftExpression, rightExpression.getType(), surrounding);
    setDesiredType(rightExpression, leftExpression.getType(), surrounding);
    if (leftExpression.getType() == rightExpression.getType()) {
        return;
    }
    // Try to apply an implicit conversion from one side to the other
    String leftTypeName = DataTypeManager.getDataTypeName(leftExpression.getType());
    String rightTypeName = DataTypeManager.getDataTypeName(rightExpression.getType());
    if (leftExpression.getType() == DataTypeManager.DefaultDataClasses.NULL) {
        ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
        return;
    }
    if (rightExpression.getType() == DataTypeManager.DefaultDataClasses.NULL) {
        ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
        return;
    }
    boolean leftChar = isCharacter(leftExpression, true);
    boolean rightChar = isCharacter(rightExpression, true);
    // Special cases when right expression is a constant
    if (rightExpression instanceof Constant && (!leftChar || rightChar)) {
        // Auto-convert constant string on right to expected type on left
        try {
            ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
            return;
        } catch (QueryResolverException qre) {
            if (rightChar && !metadata.widenComparisonToString()) {
                throw qre;
            }
        }
    }
    // Special cases when left expression is a constant
    if (leftExpression instanceof Constant && (!rightChar || leftChar)) {
        // Auto-convert constant string on left to expected type on right
        try {
            ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
            return;
        } catch (QueryResolverException qre) {
            if (leftChar && !metadata.widenComparisonToString()) {
                throw qre;
            }
        }
    }
    if ((rightChar ^ leftChar) && !metadata.widenComparisonToString()) {
        throw new QueryResolverException(QueryPlugin.Event.TEIID31172, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31172, surrounding));
    }
    if (ResolverUtil.canImplicitlyConvert(leftTypeName, rightTypeName)) {
        ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
        return;
    }
    if (ResolverUtil.canImplicitlyConvert(rightTypeName, leftTypeName)) {
        ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
        return;
    }
    String commonType = ResolverUtil.getCommonRuntimeType(new String[] { leftTypeName, rightTypeName });
    if (commonType == null) {
        // Neither are aggs, but types can't be reconciled
        throw new QueryResolverException(QueryPlugin.Event.TEIID30072, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30072, new Object[] { leftTypeName, rightTypeName, surrounding }));
    }
    ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, commonType, metadata));
    ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, commonType, metadata));
}
Also used : ExceptionExpression(org.teiid.query.sql.proc.ExceptionExpression) LanguageObject(org.teiid.query.sql.LanguageObject) QueryResolverException(org.teiid.api.exception.query.QueryResolverException)

Example 24 with LanguageObject

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

the class ValidationVisitor method visit.

@Override
public void visit(BranchingStatement obj) {
    boolean matchedLabel = false;
    boolean inLoop = false;
    for (LanguageObject lo : stack) {
        if (lo instanceof LoopStatement || lo instanceof WhileStatement) {
            inLoop = true;
            if (obj.getLabel() == null) {
                break;
            }
            matchedLabel |= obj.getLabel().equalsIgnoreCase(((Labeled) lo).getLabel());
        } else if (obj.getLabel() != null && lo instanceof Block && obj.getLabel().equalsIgnoreCase(((Block) lo).getLabel())) {
            matchedLabel = true;
            if (obj.getMode() != BranchingMode.LEAVE) {
                // $NON-NLS-1$
                handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.invalid_label", obj.getLabel()), obj);
            }
        }
    }
    if (obj.getMode() != BranchingMode.LEAVE && !inLoop) {
        // $NON-NLS-1$
        handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.no_loop"), obj);
    }
    if (obj.getLabel() != null && !matchedLabel) {
        // $NON-NLS-1$
        handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.unknown_block_label", obj.getLabel()), obj);
    }
}
Also used : Labeled(org.teiid.query.sql.proc.Statement.Labeled) Block(org.teiid.query.sql.proc.Block) LoopStatement(org.teiid.query.sql.proc.LoopStatement) WhileStatement(org.teiid.query.sql.proc.WhileStatement) LanguageObject(org.teiid.query.sql.LanguageObject)

Example 25 with LanguageObject

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

the class CommandCollectorVisitor method getCommands.

public static final List<Command> getCommands(Command command, boolean includeExpanded) {
    CommandCollectorVisitor visitor = new CommandCollectorVisitor();
    visitor.collectExpanded = includeExpanded;
    final boolean visitCommands = command instanceof SetQuery;
    PreOrderNavigator navigator = new PreOrderNavigator(visitor) {

        @Override
        protected void visitNode(LanguageObject obj) {
            if (!visitCommands && obj instanceof Command) {
                return;
            }
            super.visitNode(obj);
        }
    };
    command.acceptVisitor(navigator);
    return visitor.getCommands();
}
Also used : PreOrderNavigator(org.teiid.query.sql.navigator.PreOrderNavigator) 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