Search in sources :

Example 61 with TeiidProcessingException

use of org.teiid.core.TeiidProcessingException in project teiid by teiid.

the class TextAgg method addInputDirect.

/**
 * @throws TeiidProcessingException
 * @throws TeiidComponentException
 * @see org.teiid.query.function.aggregate.AggregateFunction#addInputDirect(List, CommandContext, CommandContext)
 */
public void addInputDirect(Object input, List<?> tuple, CommandContext commandContext) throws TeiidComponentException, TeiidProcessingException {
    try {
        if (this.result == null) {
            this.result = buildResult(commandContext);
        }
        Array in = (Array) input;
        Writer w = result.getWriter();
        writeList(w, (Object[]) in.getArray());
        w.flush();
    } catch (SQLException e) {
        throw new TeiidProcessingException(QueryPlugin.Event.TEIID30421, e);
    } catch (IOException e) {
        throw new TeiidProcessingException(QueryPlugin.Event.TEIID30421, e);
    }
}
Also used : Array(java.sql.Array) SQLException(java.sql.SQLException) IOException(java.io.IOException) Writer(java.io.Writer) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Example 62 with TeiidProcessingException

use of org.teiid.core.TeiidProcessingException in project teiid by teiid.

the class TextAgg method getResult.

/**
 * @see org.teiid.query.function.aggregate.AggregateFunction#getResult(CommandContext)
 */
public Object getResult(CommandContext commandContext) throws TeiidProcessingException {
    if (this.result == null) {
        this.result = buildResult(commandContext);
    }
    try {
        FileStoreOutputStream fs = this.result.getOuputStream();
        fs.close();
        if (fs.bytesWritten()) {
            return new BlobType(new BlobImpl(result));
        }
        return new BlobType(new SerialBlob(Arrays.copyOf(fs.getBuffer(), fs.getCount())));
    } catch (IOException e) {
        throw new TeiidProcessingException(QueryPlugin.Event.TEIID30422, e);
    } catch (SQLException e) {
        throw new TeiidProcessingException(QueryPlugin.Event.TEIID30423, e);
    }
}
Also used : BlobType(org.teiid.core.types.BlobType) SQLException(java.sql.SQLException) SerialBlob(javax.sql.rowset.serial.SerialBlob) FileStoreOutputStream(org.teiid.common.buffer.FileStore.FileStoreOutputStream) IOException(java.io.IOException) BlobImpl(org.teiid.core.types.BlobImpl) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Example 63 with TeiidProcessingException

use of org.teiid.core.TeiidProcessingException in project teiid by teiid.

the class PlanToProcessConverter method convertNode.

protected RelationalNode convertNode(PlanNode node) throws TeiidComponentException, TeiidProcessingException {
    RelationalNode processNode = null;
    switch(node.getType()) {
        case NodeConstants.Types.PROJECT:
            GroupSymbol intoGroup = (GroupSymbol) node.getProperty(NodeConstants.Info.INTO_GROUP);
            if (intoGroup != null) {
                try {
                    Insert insert = (Insert) node.getFirstChild().getProperty(Info.VIRTUAL_COMMAND);
                    List<ElementSymbol> allIntoElements = insert.getVariables();
                    Object groupID = intoGroup.getMetadataID();
                    Object modelID = metadata.getModelID(groupID);
                    String modelName = metadata.getFullName(modelID);
                    if (metadata.isVirtualGroup(groupID) && !metadata.isTemporaryTable(groupID)) {
                        InsertPlanExecutionNode ipen = new InsertPlanExecutionNode(getID(), metadata);
                        ProcessorPlan plan = (ProcessorPlan) node.getFirstChild().getProperty(Info.PROCESSOR_PLAN);
                        Assertion.isNotNull(plan);
                        ipen.setProcessorPlan(plan);
                        ipen.setReferences(insert.getValues());
                        processNode = ipen;
                    } else {
                        ProjectIntoNode pinode = new ProjectIntoNode(getID());
                        pinode.setIntoGroup(intoGroup);
                        pinode.setIntoElements(allIntoElements);
                        pinode.setModelName(modelName);
                        pinode.setConstraint((Criteria) node.getProperty(Info.CONSTRAINT));
                        pinode.setSourceHint((SourceHint) node.getProperty(Info.SOURCE_HINT));
                        if (node.hasBooleanProperty(Info.UPSERT)) {
                            pinode.setUpsert(true);
                        }
                        processNode = pinode;
                        SourceCapabilities caps = capFinder.findCapabilities(modelName);
                        if (caps.supportsCapability(Capability.INSERT_WITH_ITERATOR)) {
                            pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.ITERATOR);
                        } else if (caps.supportsCapability(Capability.BATCHED_UPDATES)) {
                            pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.BATCH);
                        } else {
                            pinode.setMode(org.teiid.query.processor.relational.ProjectIntoNode.Mode.SINGLE);
                        }
                        pinode.setTransactionSupport((TransactionSupport) caps.getSourceProperty(Capability.TRANSACTION_SUPPORT));
                    }
                } catch (QueryMetadataException e) {
                    throw new TeiidComponentException(QueryPlugin.Event.TEIID30247, e);
                }
            } else {
                List<Expression> symbols = (List) node.getProperty(NodeConstants.Info.PROJECT_COLS);
                ProjectNode pnode = new ProjectNode(getID());
                pnode.setSelectSymbols(symbols);
                processNode = pnode;
                if (node.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
                    WindowFunctionProjectNode wfpn = new WindowFunctionProjectNode(getID());
                    // with partial projection the window function may already be pushed, we'll check for that here
                    ArrayList<Expression> filtered = new ArrayList<Expression>();
                    List<Expression> childSymbols = (List) node.getFirstChild().getProperty(NodeConstants.Info.OUTPUT_COLS);
                    for (Expression ex : symbols) {
                        ex = SymbolMap.getExpression(ex);
                        if (childSymbols.contains(ex)) {
                            continue;
                        }
                        filtered.add(ex);
                    }
                    Set<WindowFunction> windowFunctions = RuleAssignOutputElements.getWindowFunctions(filtered);
                    if (!windowFunctions.isEmpty()) {
                        // TODO: check for selecting all window functions
                        List<Expression> outputElements = new ArrayList<Expression>(windowFunctions);
                        // collect the other projected expressions
                        for (Expression singleElementSymbol : (List<Expression>) node.getFirstChild().getProperty(Info.OUTPUT_COLS)) {
                            outputElements.add(singleElementSymbol);
                        }
                        wfpn.setElements(outputElements);
                        wfpn.init();
                        pnode.addChild(wfpn);
                        for (WindowFunction wf : windowFunctions) {
                            validateAggregateFunctionEvaluation(wf.getFunction());
                        }
                    }
                }
            }
            break;
        case NodeConstants.Types.JOIN:
            JoinType jtype = (JoinType) node.getProperty(NodeConstants.Info.JOIN_TYPE);
            JoinStrategyType stype = (JoinStrategyType) node.getProperty(NodeConstants.Info.JOIN_STRATEGY);
            JoinNode jnode = new JoinNode(getID());
            jnode.setJoinType(jtype);
            jnode.setLeftDistinct(node.hasBooleanProperty(NodeConstants.Info.IS_LEFT_DISTINCT));
            jnode.setRightDistinct(node.hasBooleanProperty(NodeConstants.Info.IS_RIGHT_DISTINCT));
            List joinCrits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
            String depValueSource = (String) node.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE);
            SortOption leftSort = (SortOption) node.getProperty(NodeConstants.Info.SORT_LEFT);
            if (stype == JoinStrategyType.MERGE || stype == JoinStrategyType.ENHANCED_SORT) {
                MergeJoinStrategy mjStrategy = null;
                if (stype.equals(JoinStrategyType.ENHANCED_SORT)) {
                    EnhancedSortMergeJoinStrategy esmjStrategy = new EnhancedSortMergeJoinStrategy(leftSort, (SortOption) node.getProperty(NodeConstants.Info.SORT_RIGHT));
                    esmjStrategy.setSemiDep(node.hasBooleanProperty(Info.IS_SEMI_DEP));
                    mjStrategy = esmjStrategy;
                } else {
                    mjStrategy = new MergeJoinStrategy(leftSort, (SortOption) node.getProperty(NodeConstants.Info.SORT_RIGHT), false);
                }
                jnode.setJoinStrategy(mjStrategy);
                List leftExpressions = (List) node.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS);
                List rightExpressions = (List) node.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS);
                jnode.setJoinExpressions(leftExpressions, rightExpressions);
                joinCrits = (List) node.getProperty(NodeConstants.Info.NON_EQUI_JOIN_CRITERIA);
            } else if (stype == JoinStrategyType.NESTED_TABLE) {
                NestedTableJoinStrategy ntjStrategy = new NestedTableJoinStrategy();
                jnode.setJoinStrategy(ntjStrategy);
                SymbolMap references = (SymbolMap) node.getProperty(Info.RIGHT_NESTED_REFERENCES);
                ntjStrategy.setRightMap(references);
            } else {
                NestedLoopJoinStrategy nljStrategy = new NestedLoopJoinStrategy();
                jnode.setJoinStrategy(nljStrategy);
            }
            Criteria joinCrit = Criteria.combineCriteria(joinCrits);
            jnode.setJoinCriteria(joinCrit);
            processNode = jnode;
            jnode.setDependentValueSource(depValueSource);
            break;
        case NodeConstants.Types.ACCESS:
            ProcessorPlan plan = (ProcessorPlan) node.getProperty(NodeConstants.Info.PROCESSOR_PLAN);
            if (plan != null) {
                PlanExecutionNode peNode = null;
                Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.PROCEDURE_CRITERIA);
                if (crit != null) {
                    List references = (List) node.getProperty(NodeConstants.Info.PROCEDURE_INPUTS);
                    List defaults = (List) node.getProperty(NodeConstants.Info.PROCEDURE_DEFAULTS);
                    peNode = new DependentProcedureExecutionNode(getID(), crit, references, defaults);
                } else {
                    peNode = new PlanExecutionNode(getID());
                }
                peNode.setProcessorPlan(plan);
                processNode = peNode;
            } else {
                AccessNode aNode = null;
                Command command = (Command) node.getProperty(NodeConstants.Info.ATOMIC_REQUEST);
                Object modelID = node.getProperty(NodeConstants.Info.MODEL_ID);
                if (modelID != null) {
                    String fullName = metadata.getFullName(modelID);
                    if (!capFinder.isValid(fullName)) {
                        // TODO: we ideally want to handle the partial resutls case here differently
                        // by adding a null node / and a source warning
                        // for now it's just as easy to say that the user needs to take steps to
                        // return static capabilities
                        SourceCapabilities caps = capFinder.findCapabilities(fullName);
                        Exception cause = null;
                        if (caps != null) {
                            cause = (Exception) caps.getSourceProperty(Capability.INVALID_EXCEPTION);
                        }
                        throw new QueryPlannerException(QueryPlugin.Event.TEIID30498, cause, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30498, fullName));
                    }
                }
                EvaluatableVisitor ev = null;
                if (node.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
                    if (command instanceof StoredProcedure) {
                        List references = (List) node.getProperty(NodeConstants.Info.PROCEDURE_INPUTS);
                        List defaults = (List) node.getProperty(NodeConstants.Info.PROCEDURE_DEFAULTS);
                        Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.PROCEDURE_CRITERIA);
                        DependentProcedureAccessNode depAccessNode = new DependentProcedureAccessNode(getID(), crit, references, defaults);
                        processNode = depAccessNode;
                        aNode = depAccessNode;
                    } else {
                        // create dependent access node
                        DependentAccessNode depAccessNode = new DependentAccessNode(getID());
                        if (modelID != null) {
                            depAccessNode.setPushdown(CapabilitiesUtil.supports(Capability.DEPENDENT_JOIN, modelID, metadata, capFinder));
                            depAccessNode.setMaxSetSize(CapabilitiesUtil.getMaxInCriteriaSize(modelID, metadata, capFinder));
                            depAccessNode.setMaxPredicates(CapabilitiesUtil.getMaxDependentPredicates(modelID, metadata, capFinder));
                            depAccessNode.setUseBindings(CapabilitiesUtil.supports(Capability.DEPENDENT_JOIN_BINDINGS, modelID, metadata, capFinder));
                            // TODO: allow the translator to drive this property
                            // simplistic check of whether this query is complex to re-execute
                            Query query = (Query) command;
                            if (query.getGroupBy() != null || query.getFrom().getClauses().size() > 1 || !(query.getFrom().getClauses().get(0) instanceof UnaryFromClause) || query.getWith() != null) {
                                depAccessNode.setComplexQuery(true);
                            } else {
                                // check to see if there in an index on at least one of the dependent sets
                                Set<GroupSymbol> groups = new HashSet<GroupSymbol>(query.getFrom().getGroups());
                                boolean found = false;
                                for (Criteria crit : Criteria.separateCriteriaByAnd(query.getCriteria())) {
                                    if (crit instanceof DependentSetCriteria) {
                                        DependentSetCriteria dsc = (DependentSetCriteria) crit;
                                        if (NewCalculateCostUtil.getKeyUsed(ElementCollectorVisitor.getElements(dsc.getExpression(), true), groups, metadata, null) != null) {
                                            found = true;
                                            break;
                                        }
                                    }
                                }
                                if (!found) {
                                    depAccessNode.setComplexQuery(true);
                                }
                            }
                        }
                        processNode = depAccessNode;
                        aNode = depAccessNode;
                    }
                    aNode.setShouldEvaluateExpressions(true);
                } else {
                    // create access node
                    aNode = new AccessNode(getID());
                    processNode = aNode;
                }
                // -- special handling for system tables. currently they cannot perform projection
                try {
                    if (command instanceof Query) {
                        processNode = correctProjectionInternalTables(node, aNode);
                    }
                } catch (QueryMetadataException err) {
                    throw new TeiidComponentException(QueryPlugin.Event.TEIID30248, err);
                }
                setRoutingName(aNode, node, command);
                boolean shouldEval = false;
                if (command instanceof Insert) {
                    Insert insert = (Insert) command;
                    if (insert.getQueryExpression() != null) {
                        insert.setQueryExpression((QueryCommand) aliasCommand(aNode, insert.getQueryExpression(), modelID));
                    } else {
                        for (int i = 0; i < insert.getValues().size(); i++) {
                            Expression ex = (Expression) insert.getValues().get(i);
                            if (!CriteriaCapabilityValidatorVisitor.canPushLanguageObject(ex, modelID, metadata, capFinder, analysisRecord)) {
                                // replace with an expression symbol to let the rewriter know that it should be replaced
                                insert.getValues().set(i, new ExpressionSymbol("x", ex));
                                shouldEval = true;
                            }
                        }
                    }
                } else if (command instanceof QueryCommand) {
                    command = aliasCommand(aNode, command, modelID);
                }
                ev = EvaluatableVisitor.needsEvaluationVisitor(modelID, metadata, capFinder);
                if (!shouldEval && modelID != null) {
                    // do a capabilities sensitive check for needs eval
                    String modelName = metadata.getFullName(modelID);
                    SourceCapabilities caps = capFinder.findCapabilities(modelName);
                    final CriteriaCapabilityValidatorVisitor capVisitor = new CriteriaCapabilityValidatorVisitor(modelID, metadata, capFinder, caps);
                    capVisitor.setCheckEvaluation(false);
                    DeepPreOrderNavigator nav = new DeepPreOrderNavigator(ev) {

                        protected void visitNode(org.teiid.query.sql.LanguageObject obj) {
                            if (capVisitor.isValid() && obj instanceof Expression) {
                                obj.acceptVisitor(capVisitor);
                            }
                            super.visitNode(obj);
                        }
                    };
                    command.acceptVisitor(nav);
                    if (!capVisitor.isValid()) {
                        // there's a non-supported construct pushed, we should eval
                        ev.evaluationNotPossible(EvaluationLevel.PROCESSING);
                    }
                } else {
                    DeepPreOrderNavigator.doVisit(command, ev);
                }
                aNode.setShouldEvaluateExpressions(ev.requiresEvaluation(EvaluationLevel.PROCESSING) || shouldEval);
                aNode.setCommand(command);
                if (modelID != null) {
                    String fullName = metadata.getFullName(modelID);
                    SourceCapabilities caps = capFinder.findCapabilities(fullName);
                    aNode.setTransactionSupport((TransactionSupport) caps.getSourceProperty(Capability.TRANSACTION_SUPPORT));
                }
                Map<GroupSymbol, PlanNode> subPlans = (Map<GroupSymbol, PlanNode>) node.getProperty(Info.SUB_PLANS);
                // it makes more sense to allow the multisource affect to be elevated above just access nodes
                if (aNode.getModelId() != null && metadata.isMultiSource(aNode.getModelId())) {
                    VDBMetaData vdb = context.getVdb();
                    // forces a rewrite
                    aNode.setShouldEvaluateExpressions(true);
                    aNode.setElements((List) node.getProperty(NodeConstants.Info.OUTPUT_COLS));
                    if (node.hasBooleanProperty(Info.IS_MULTI_SOURCE)) {
                        Expression ex = rewriteMultiSourceCommand(aNode.getCommand());
                        aNode.setConnectorBindingExpression(ex);
                        aNode.setMultiSource(true);
                    } else {
                        String sourceName = (String) node.getProperty(Info.SOURCE_NAME);
                        aNode.setConnectorBindingExpression(new Constant(sourceName));
                    }
                } else if (subPlans == null) {
                    if (!aNode.isShouldEvaluate()) {
                        aNode.minimizeProject(command);
                    }
                    // check if valid to share this with other nodes
                    if (ev != null && ev.getDeterminismLevel().compareTo(Determinism.INSTRUCTION_DETERMINISTIC) >= 0 && command.areResultsCachable()) {
                        checkForSharedSourceCommand(aNode, node);
                    }
                }
                if (subPlans != null) {
                    QueryCommand qc = (QueryCommand) command;
                    if (qc.getWith() == null) {
                        qc.setWith(new ArrayList<WithQueryCommand>(subPlans.size()));
                    }
                    Map<GroupSymbol, RelationalPlan> plans = new LinkedHashMap<GroupSymbol, RelationalPlan>();
                    for (Map.Entry<GroupSymbol, PlanNode> entry : subPlans.entrySet()) {
                        RelationalPlan subPlan = convert(entry.getValue());
                        List<ElementSymbol> elems = ResolverUtil.resolveElementsInGroup(entry.getKey(), metadata);
                        subPlan.setOutputElements(elems);
                        plans.put(entry.getKey(), subPlan);
                        WithQueryCommand withQueryCommand = new WithQueryCommand(entry.getKey(), elems, null);
                        qc.getWith().add(withQueryCommand);
                    }
                    aNode.setSubPlans(plans);
                }
            }
            break;
        case NodeConstants.Types.SELECT:
            Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
            if (!node.hasCollectionProperty(Info.OUTPUT_COLS)) {
                // the late optimization to create a dependent join from a subquery introduces
                // criteria that have no output elements set
                // TODO that should be cleaner, but the logic currently expects to be run after join implementation
                // and rerunning assign output elements seems excessive
                node.setProperty(Info.OUTPUT_COLS, node.getFirstChild().getProperty(Info.OUTPUT_COLS));
            }
            SelectNode selnode = new SelectNode(getID());
            selnode.setCriteria(crit);
            // in case the parent was a source
            selnode.setProjectedExpressions((List<Expression>) node.getProperty(NodeConstants.Info.PROJECT_COLS));
            processNode = selnode;
            break;
        case NodeConstants.Types.SORT:
        case NodeConstants.Types.DUP_REMOVE:
            if (node.getType() == NodeConstants.Types.DUP_REMOVE) {
                processNode = new DupRemoveNode(getID());
            } else {
                SortNode sortNode = new SortNode(getID());
                OrderBy orderBy = (OrderBy) node.getProperty(NodeConstants.Info.SORT_ORDER);
                if (orderBy != null) {
                    sortNode.setSortElements(orderBy.getOrderByItems());
                }
                if (node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL)) {
                    sortNode.setMode(Mode.DUP_REMOVE_SORT);
                }
                processNode = sortNode;
            }
            break;
        case NodeConstants.Types.GROUP:
            GroupingNode gnode = new GroupingNode(getID());
            gnode.setRollup(node.hasBooleanProperty(Info.ROLLUP));
            SymbolMap groupingMap = (SymbolMap) node.getProperty(NodeConstants.Info.SYMBOL_MAP);
            gnode.setOutputMapping(groupingMap);
            gnode.setRemoveDuplicates(node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL));
            List<Expression> gCols = (List) node.getProperty(NodeConstants.Info.GROUP_COLS);
            OrderBy orderBy = (OrderBy) node.getProperty(Info.SORT_ORDER);
            if (orderBy == null) {
                if (gCols != null) {
                    LinkedHashSet<Expression> exprs = new LinkedHashSet<Expression>();
                    for (Expression ex : gCols) {
                        exprs.add(SymbolMap.getExpression(ex));
                    }
                    orderBy = new OrderBy(RuleChooseJoinStrategy.createExpressionSymbols(new ArrayList<Expression>(exprs)));
                }
            } else {
                HashSet<Expression> seen = new HashSet<Expression>();
                for (int i = 0; i < gCols.size(); i++) {
                    if (i < orderBy.getOrderByItems().size()) {
                        OrderByItem orderByItem = orderBy.getOrderByItems().get(i);
                        Expression ex = SymbolMap.getExpression(orderByItem.getSymbol());
                        if (!seen.add(ex)) {
                            continue;
                        }
                        if (ex instanceof ElementSymbol) {
                            ex = groupingMap.getMappedExpression((ElementSymbol) ex);
                            // $NON-NLS-1$
                            orderByItem.setSymbol(new ExpressionSymbol("expr", ex));
                        }
                    } else {
                        // $NON-NLS-1$
                        orderBy.addVariable(new ExpressionSymbol("expr", gCols.get(i)), OrderBy.ASC);
                    }
                }
            }
            if (orderBy != null) {
                gnode.setOrderBy(orderBy.getOrderByItems());
            }
            for (Expression ex : groupingMap != null ? groupingMap.getValues() : (List<Expression>) node.getFirstChild().getProperty(NodeConstants.Info.PROJECT_COLS)) {
                if (ex instanceof AggregateSymbol) {
                    validateAggregateFunctionEvaluation((AggregateSymbol) ex);
                }
            }
            processNode = gnode;
            break;
        case NodeConstants.Types.SOURCE:
            Object source = node.getProperty(NodeConstants.Info.TABLE_FUNCTION);
            if (source instanceof XMLTable) {
                XMLTable xt = (XMLTable) source;
                XMLTableNode xtn = new XMLTableNode(getID());
                // we handle the projection filtering once here rather than repeating the
                // path analysis on a per plan basis
                updateGroupName(node, xt);
                Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
                List cols = (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
                int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
                ArrayList<XMLColumn> filteredColumns = new ArrayList<XMLColumn>(projectionIndexes.length);
                for (int col : projectionIndexes) {
                    filteredColumns.add(xt.getColumns().get(col));
                }
                xt.getXQueryExpression().useDocumentProjection(filteredColumns, analysisRecord);
                xtn.setProjectedColumns(filteredColumns);
                xtn.setTable(xt);
                processNode = xtn;
                break;
            }
            if (source instanceof ObjectTable) {
                ObjectTable ot = (ObjectTable) source;
                ObjectTableNode otn = new ObjectTableNode(getID());
                // we handle the projection filtering once here rather than repeating the
                // path analysis on a per plan basis
                updateGroupName(node, ot);
                Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(ot.getProjectedSymbols());
                List<Expression> cols = (List<Expression>) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
                int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
                ArrayList<ObjectColumn> filteredColumns = new ArrayList<ObjectColumn>(projectionIndexes.length);
                for (int col : projectionIndexes) {
                    filteredColumns.add(ot.getColumns().get(col));
                }
                otn.setProjectedColumns(filteredColumns);
                otn.setTable(ot);
                processNode = otn;
                break;
            }
            if (source instanceof TextTable) {
                TextTableNode ttn = new TextTableNode(getID());
                TextTable tt = (TextTable) source;
                updateGroupName(node, tt);
                ttn.setTable(tt);
                processNode = ttn;
                break;
            }
            if (source instanceof ArrayTable) {
                ArrayTableNode atn = new ArrayTableNode(getID());
                ArrayTable at = (ArrayTable) source;
                updateGroupName(node, at);
                atn.setTable(at);
                processNode = atn;
                break;
            }
            SymbolMap symbolMap = (SymbolMap) node.getProperty(NodeConstants.Info.SYMBOL_MAP);
            if (symbolMap != null) {
                PlanNode child = node.getLastChild();
                if (child.getType() == NodeConstants.Types.PROJECT || child.getType() == NodeConstants.Types.SELECT) {
                    // update the project cols based upon the original output
                    child.setProperty(NodeConstants.Info.PROJECT_COLS, child.getProperty(NodeConstants.Info.OUTPUT_COLS));
                }
                if (child.getType() != NodeConstants.Types.SET_OP || child.getProperty(Info.SET_OPERATION) == Operation.UNION) {
                    child.setProperty(NodeConstants.Info.OUTPUT_COLS, node.getProperty(NodeConstants.Info.OUTPUT_COLS));
                } else {
                    // else we cannot directly update the child properties as the child will get converted to a join
                    // create a projection instead for initialization purposes, but won't impact performance
                    ProjectNode pNode = new ProjectNode(getID());
                    pNode.setSelectSymbols((List<? extends Expression>) child.getProperty(NodeConstants.Info.OUTPUT_COLS));
                    return prepareToAdd(node, pNode);
                }
            }
            return null;
        case NodeConstants.Types.SET_OP:
            Operation setOp = (Operation) node.getProperty(NodeConstants.Info.SET_OPERATION);
            boolean useAll = ((Boolean) node.getProperty(NodeConstants.Info.USE_ALL)).booleanValue();
            if (setOp == Operation.UNION) {
                RelationalNode unionAllNode = new UnionAllNode(getID());
                if (useAll) {
                    processNode = unionAllNode;
                } else {
                    boolean onlyDupRemoval = node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL);
                    if (onlyDupRemoval) {
                        processNode = new DupRemoveNode(getID());
                    } else {
                        SortNode sNode = new SortNode(getID());
                        sNode.setMode(Mode.DUP_REMOVE_SORT);
                        processNode = sNode;
                    }
                    unionAllNode.setElements((List) node.getProperty(NodeConstants.Info.OUTPUT_COLS));
                    processNode.addChild(unionAllNode);
                }
            } else {
                JoinNode joinAsSet = new JoinNode(getID());
                joinAsSet.setJoinStrategy(new MergeJoinStrategy(SortOption.SORT_DISTINCT, SortOption.SORT_DISTINCT, true));
                // If we push these sorts, we will have to enforce null order, since nulls are equal here
                List leftExpressions = (List) node.getFirstChild().getProperty(NodeConstants.Info.OUTPUT_COLS);
                List rightExpressions = (List) node.getLastChild().getProperty(NodeConstants.Info.OUTPUT_COLS);
                joinAsSet.setJoinType(setOp == Operation.EXCEPT ? JoinType.JOIN_ANTI_SEMI : JoinType.JOIN_SEMI);
                joinAsSet.setJoinExpressions(leftExpressions, rightExpressions);
                processNode = joinAsSet;
            }
            break;
        case NodeConstants.Types.TUPLE_LIMIT:
            Expression rowLimit = (Expression) node.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
            Expression offset = (Expression) node.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
            LimitNode ln = new LimitNode(getID(), rowLimit, offset);
            ln.setImplicit(node.hasBooleanProperty(Info.IS_IMPLICIT_LIMIT));
            processNode = ln;
            break;
        case NodeConstants.Types.NULL:
            processNode = new NullNode(getID());
            break;
        default:
            throw new QueryPlannerException(QueryPlugin.Event.TEIID30250, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30250, NodeConstants.getNodeTypeString(node.getType())));
    }
    if (processNode != null) {
        processNode = prepareToAdd(node, processNode);
    }
    return processNode;
}
Also used : ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol) DeepPreOrderNavigator(org.teiid.query.sql.navigator.DeepPreOrderNavigator) XMLColumn(org.teiid.query.sql.lang.XMLTable.XMLColumn) VDBMetaData(org.teiid.adminapi.impl.VDBMetaData) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) TeiidComponentException(org.teiid.core.TeiidComponentException) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) SymbolMap(org.teiid.query.sql.util.SymbolMap) ObjectColumn(org.teiid.query.sql.lang.ObjectTable.ObjectColumn) CriteriaCapabilityValidatorVisitor(org.teiid.query.optimizer.relational.rules.CriteriaCapabilityValidatorVisitor) JoinStrategyType(org.teiid.query.processor.relational.JoinNode.JoinStrategyType) EvaluatableVisitor(org.teiid.query.sql.visitor.EvaluatableVisitor) Expression(org.teiid.query.sql.symbol.Expression) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities) WindowFunction(org.teiid.query.sql.symbol.WindowFunction) SortOption(org.teiid.query.processor.relational.MergeJoinStrategy.SortOption) SymbolMap(org.teiid.query.sql.util.SymbolMap) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) ProcessorPlan(org.teiid.query.processor.ProcessorPlan) ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) Constant(org.teiid.query.sql.symbol.Constant) Operation(org.teiid.query.sql.lang.SetQuery.Operation) PlanNode(org.teiid.query.optimizer.relational.plantree.PlanNode) TeiidComponentException(org.teiid.core.TeiidComponentException) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException) SpecificHint(org.teiid.query.sql.lang.SourceHint.SpecificHint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 64 with TeiidProcessingException

use of org.teiid.core.TeiidProcessingException in project teiid by teiid.

the class RowBasedSecurityHelper method checkUpdateRowBasedFilters.

public static Command checkUpdateRowBasedFilters(ProcedureContainer container, Command procedure, RelationalPlanner planner) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException, QueryResolverException {
    if (container instanceof StoredProcedure) {
        return procedure;
    }
    Criteria filter = RowBasedSecurityHelper.getRowBasedFilters(planner.metadata, container.getGroup(), planner.context, false);
    if (filter == null) {
        return procedure;
    }
    addFilter(container, planner, filter);
    // we won't enforce on the update side through a virtual
    if (procedure != null) {
        return procedure;
    }
    filter = RowBasedSecurityHelper.getRowBasedFilters(planner.metadata, container.getGroup(), planner.context, true);
    if (filter == null) {
        return procedure;
    }
    // TODO: alter the compensation logic in RelationalPlanner to produce an row-by-row check for insert/update
    // check constraints
    Map<ElementSymbol, Expression> values = null;
    boolean compensate = false;
    if (container instanceof Update) {
        Collection<ElementSymbol> elems = ElementCollectorVisitor.getElements(filter, true);
        // check the change set against the filter
        values = new HashMap<ElementSymbol, Expression>();
        Update update = (Update) container;
        boolean constraintApplicable = false;
        for (SetClause clause : update.getChangeList().getClauses()) {
            if (!elems.contains(clause.getSymbol())) {
                continue;
            }
            constraintApplicable = true;
            // TODO: do this is a single eval pass
            if (EvaluatableVisitor.isFullyEvaluatable(clause.getValue(), true)) {
                values.put(clause.getSymbol(), clause.getValue());
            } else if (!compensate && !EvaluatableVisitor.isFullyEvaluatable(clause.getValue(), false)) {
                compensate = true;
            }
        }
        if (!constraintApplicable) {
            return procedure;
        }
    // TOOD: decompose the where clause to see if there are any more static
    // values that can be plugged in
    } else if (container instanceof Insert) {
        Insert insert = (Insert) container;
        if (insert.getQueryExpression() == null) {
            values = new HashMap<ElementSymbol, Expression>();
            Collection<ElementSymbol> insertElmnts = ResolverUtil.resolveElementsInGroup(insert.getGroup(), planner.metadata);
            for (ElementSymbol elementSymbol : insertElmnts) {
                Expression value = null;
                int index = insert.getVariables().indexOf(elementSymbol);
                if (index == -1) {
                    value = ResolverUtil.getDefault(elementSymbol, planner.metadata);
                    values.put(elementSymbol, value);
                } else {
                    value = (Expression) insert.getValues().get(index);
                    if (EvaluatableVisitor.isFullyEvaluatable(value, true)) {
                        values.put(elementSymbol, value);
                    }
                }
            }
        } else {
            validateAndPlanSubqueries(filter, container.getGroup(), planner);
            insert.setConstraint(filter);
        }
    }
    if (values != null) {
        if (!values.isEmpty()) {
            ExpressionMappingVisitor.mapExpressions(filter, values);
            filter = QueryRewriter.rewriteCriteria(filter, planner.context, planner.metadata);
        }
        if (filter != QueryRewriter.TRUE_CRITERIA) {
            if (filter == QueryRewriter.FALSE_CRITERIA || filter == QueryRewriter.UNKNOWN_CRITERIA) {
                throw new TeiidProcessingException(QueryPlugin.Event.TEIID31130, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31130, container));
            }
            if (container instanceof Update) {
                Collection<ElementSymbol> elems = ElementCollectorVisitor.getElements(filter, true);
                Update update = (Update) container;
                if (!Collections.disjoint(elems, update.getChangeList().getClauseMap().keySet())) {
                    validateAndPlanSubqueries(filter, container.getGroup(), planner);
                    update.setConstraint(filter);
                    if (compensate) {
                        try {
                            planner.validateRowProcessing(container);
                        } catch (QueryPlannerException e) {
                            throw new TeiidProcessingException(QueryPlugin.Event.TEIID31131, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31131, container));
                        }
                        return QueryRewriter.createUpdateProcedure((Update) container, planner.metadata, planner.context);
                    }
                }
            } else if (container instanceof Insert) {
                validateAndPlanSubqueries(filter, container.getGroup(), planner);
                ((Insert) container).setConstraint(filter);
            }
        }
    }
    return procedure;
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) HashMap(java.util.HashMap) TeiidProcessingException(org.teiid.core.TeiidProcessingException) Expression(org.teiid.query.sql.symbol.Expression) Collection(java.util.Collection) QueryPlannerException(org.teiid.api.exception.query.QueryPlannerException)

Example 65 with TeiidProcessingException

use of org.teiid.core.TeiidProcessingException in project teiid by teiid.

the class RuleCollapseSource method processOrderBy.

private void processOrderBy(PlanNode node, QueryCommand query, Object modelID, CommandContext context, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
    boolean userOrdering = NodeEditor.findParent(node, NodeConstants.Types.JOIN | NodeConstants.Types.SOURCE) == null;
    OrderBy orderBy = (OrderBy) node.getProperty(NodeConstants.Info.SORT_ORDER);
    query.setOrderBy(orderBy);
    if (query instanceof Query) {
        List<Expression> cols = query.getProjectedSymbols();
        List<Expression> exprs = new ArrayList<Expression>(cols.size());
        for (Expression expr : cols) {
            exprs.add(SymbolMap.getExpression(expr));
        }
        for (OrderByItem item : orderBy.getOrderByItems()) {
            item.setExpressionPosition(exprs.indexOf(SymbolMap.getExpression(item.getSymbol())));
        }
        try {
            QueryRewriter.rewriteOrderBy(query, orderBy, query.getProjectedSymbols(), context, context.getMetadata());
        } catch (TeiidProcessingException e) {
            throw new TeiidComponentException(e);
        }
    }
    boolean supportsNullOrdering = CapabilitiesUtil.supports(Capability.QUERY_ORDERBY_NULL_ORDERING, modelID, context.getMetadata(), capFinder);
    NullOrder defaultNullOrder = CapabilitiesUtil.getDefaultNullOrder(modelID, context.getMetadata(), capFinder);
    for (OrderByItem item : orderBy.getOrderByItems()) {
        if (item.getNullOrdering() != null) {
            if (!supportsNullOrdering) {
                item.setNullOrdering(null);
            }
        } else if (userOrdering && supportsNullOrdering && defaultNullOrder != context.getOptions().getDefaultNullOrder() && context.getOptions().isPushdownDefaultNullOrder()) {
            // try to match the expected default
            if (item.isAscending()) {
                if (context.getOptions().getDefaultNullOrder() == NullOrder.FIRST || context.getOptions().getDefaultNullOrder() == NullOrder.LOW) {
                    if (defaultNullOrder != NullOrder.FIRST && defaultNullOrder != NullOrder.LOW) {
                        item.setNullOrdering(NullOrdering.FIRST);
                    }
                } else {
                    if (defaultNullOrder != NullOrder.LAST && defaultNullOrder != NullOrder.HIGH) {
                        item.setNullOrdering(NullOrdering.LAST);
                    }
                }
            } else {
                if (context.getOptions().getDefaultNullOrder() == NullOrder.LAST || context.getOptions().getDefaultNullOrder() == NullOrder.LOW) {
                    if (defaultNullOrder != NullOrder.LAST && defaultNullOrder != NullOrder.LOW) {
                        item.setNullOrdering(NullOrdering.LAST);
                    }
                } else {
                    if (defaultNullOrder != NullOrder.FIRST && defaultNullOrder != NullOrder.HIGH) {
                        item.setNullOrdering(NullOrdering.FIRST);
                    }
                }
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) NullOrder(org.teiid.translator.ExecutionFactory.NullOrder) TeiidComponentException(org.teiid.core.TeiidComponentException) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Aggregations

TeiidProcessingException (org.teiid.core.TeiidProcessingException)92 TeiidComponentException (org.teiid.core.TeiidComponentException)30 IOException (java.io.IOException)17 ArrayList (java.util.ArrayList)17 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)17 SQLException (java.sql.SQLException)16 BlockedException (org.teiid.common.buffer.BlockedException)16 Test (org.junit.Test)14 CommandContext (org.teiid.query.util.CommandContext)14 LanguageObject (org.teiid.query.sql.LanguageObject)13 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)13 GroupSymbol (org.teiid.query.sql.symbol.GroupSymbol)12 List (java.util.List)11 QueryMetadataInterface (org.teiid.query.metadata.QueryMetadataInterface)10 TransformationMetadata (org.teiid.query.metadata.TransformationMetadata)10 QueryPlannerException (org.teiid.api.exception.query.QueryPlannerException)9 TupleSource (org.teiid.common.buffer.TupleSource)9 TupleBatch (org.teiid.common.buffer.TupleBatch)8 CollectionTupleSource (org.teiid.query.processor.CollectionTupleSource)7 BasicSourceCapabilities (org.teiid.query.optimizer.capabilities.BasicSourceCapabilities)6