Search in sources :

Example 21 with TupleBuffer

use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.

the class TempTable method update.

public TupleSource update(Criteria crit, final SetClauseList update) throws TeiidComponentException, ExpressionEvaluationException, TeiidProcessingException {
    final boolean primaryKeyChangePossible = canChangePrimaryKey(update);
    final TupleBrowser browser = createTupleBrower(crit, OrderBy.ASC);
    UpdateProcessor up = new UpdateProcessor(crit, browser, true) {

        protected TupleBuffer changeSet;

        protected UpdateProcessor changeSetProcessor;

        @Override
        protected void tuplePassed(List tuple) throws BlockedException, TeiidComponentException, TeiidProcessingException {
            List<Object> newTuple = new ArrayList<Object>(tuple);
            for (Map.Entry<ElementSymbol, Expression> entry : update.getClauseMap().entrySet()) {
                newTuple.set(columnMap.get(entry.getKey()), eval.evaluate(entry.getValue(), tuple));
            }
            validateNotNull(newTuple);
            if (primaryKeyChangePossible) {
                browser.removed();
                deleteTuple(tuple);
                if (changeSet == null) {
                    changeSet = bm.createTupleBuffer(columns, sessionID, TupleSourceType.PROCESSOR);
                }
                changeSet.addTuple(newTuple);
            } else {
                browser.update(newTuple);
            }
        }

        @Override
        protected void undo(List<?> tuple) throws TeiidComponentException, TeiidProcessingException {
            if (primaryKeyChangePossible) {
                insertTuple(tuple, false, true);
            } else {
                updateTuple(tuple);
            }
        }

        @Override
        void success() throws TeiidComponentException, ExpressionEvaluationException, TeiidProcessingException {
            // changeSet contains possible updates
            if (primaryKeyChangePossible) {
                changeSet.close();
                if (changeSetProcessor == null) {
                    changeSetProcessor = new InsertUpdateProcessor(changeSet.createIndexedTupleSource(true), false, null, true, false);
                }
                // when this returns, we're up to date
                changeSetProcessor.process();
            }
        }

        @Override
        public void close() {
            super.close();
            changeSetProcessor = null;
            if (changeSet != null) {
                changeSet.remove();
                changeSet = null;
            }
        }
    };
    long updateCount = up.process();
    tid.getTableData().dataModified(updateCount);
    return CollectionTupleSource.createUpdateCountTupleSource((int) Math.min(Integer.MAX_VALUE, updateCount));
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) TupleBuffer(org.teiid.common.buffer.TupleBuffer) ArrayList(java.util.ArrayList) Expression(org.teiid.query.sql.symbol.Expression) SetClauseList(org.teiid.query.sql.lang.SetClauseList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TupleBrowser(org.teiid.common.buffer.TupleBrowser)

Example 22 with TupleBuffer

use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.

the class TempTable method createTupleSource.

private TupleSource createTupleSource(final List<? extends Expression> projectedCols, final Criteria condition, OrderBy orderBy, IndexInfo ii, boolean agg) throws TeiidComponentException, TeiidProcessingException {
    TupleBrowser browser = ii.createTupleBrowser(bm.getOptions().getDefaultNullOrder(), true);
    TupleSource ts = new QueryTupleSource(browser, columnMap, agg ? getColumns() : projectedCols, condition);
    boolean usingQueryTupleSource = false;
    boolean success = false;
    TupleBuffer tb = null;
    try {
        if (ii.ordering == null && orderBy != null) {
            SortUtility sort = new SortUtility(ts, orderBy.getOrderByItems(), Mode.SORT, bm, sessionID, projectedCols);
            sort.setNonBlocking(true);
            tb = sort.sort();
        } else if (agg) {
            int count = 0;
            while (ts.nextTuple() != null) {
                count++;
            }
            success = true;
            return new CollectionTupleSource(Arrays.asList(Collections.nCopies(projectedCols.size(), count)).iterator());
        } else if (updatable) {
            tb = bm.createTupleBuffer(projectedCols, sessionID, TupleSourceType.PROCESSOR);
            List<?> next = null;
            while ((next = ts.nextTuple()) != null) {
                tb.addTuple(next);
            }
        } else {
            usingQueryTupleSource = true;
            success = true;
            return ts;
        }
        tb.close();
        success = true;
        return tb.createIndexedTupleSource(true);
    } finally {
        if (!success && tb != null) {
            tb.remove();
        }
        if (!usingQueryTupleSource) {
            // ensure the buffers get released
            ts.closeSource();
        }
    }
}
Also used : SortUtility(org.teiid.query.processor.relational.SortUtility) TupleBufferTupleSource(org.teiid.common.buffer.TupleBuffer.TupleBufferTupleSource) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) TupleSource(org.teiid.common.buffer.TupleSource) TupleBuffer(org.teiid.common.buffer.TupleBuffer) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) TupleBrowser(org.teiid.common.buffer.TupleBrowser)

Example 23 with TupleBuffer

use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.

the class DataTierManagerImpl method registerRequest.

public TupleSource registerRequest(CommandContext context, Command command, String modelName, final RegisterRequestParameter parameterObject) throws TeiidComponentException, TeiidProcessingException {
    RequestWorkItem workItem = context.getWorkItem();
    Assertion.isNotNull(workItem);
    if (CoreConstants.SYSTEM_MODEL.equals(modelName) || CoreConstants.SYSTEM_ADMIN_MODEL.equals(modelName)) {
        return processSystemQuery(context, command, workItem.getDqpWorkContext());
    }
    AtomicRequestMessage aqr = createRequest(workItem, command, modelName, parameterObject.connectorBindingId, parameterObject.nodeID);
    aqr.setCommandContext(context);
    if (parameterObject.fetchSize > 0) {
        aqr.setFetchSize(2 * parameterObject.fetchSize);
    }
    if (parameterObject.limit > 0) {
        aqr.setFetchSize(Math.min(parameterObject.limit, aqr.getFetchSize()));
    }
    aqr.setCopyStreamingLobs(parameterObject.copyStreamingLobs);
    Collection<GroupSymbol> accessedGroups = null;
    if (context.getDataObjects() != null) {
        QueryMetadataInterface metadata = context.getMetadata();
        accessedGroups = GroupCollectorVisitor.getGroupsIgnoreInlineViews(command, false);
        boolean usedModel = false;
        for (GroupSymbol gs : accessedGroups) {
            context.accessedDataObject(gs.getMetadataID());
            // check the source/tables/procs for determinism level
            Object mid = gs.getMetadataID();
            if (mid instanceof TempMetadataID) {
                TempMetadataID tid = (TempMetadataID) mid;
                if (tid.getOriginalMetadataID() != null) {
                    mid = tid.getOriginalMetadataID();
                }
            }
            String specificProp = metadata.getExtensionProperty(mid, AbstractMetadataRecord.RELATIONAL_URI + DDLConstants.DETERMINISM, false);
            if (specificProp == null) {
                if (!usedModel) {
                    Object modelId = metadata.getModelID(mid);
                    String prop = metadata.getExtensionProperty(modelId, AbstractMetadataRecord.RELATIONAL_URI + DDLConstants.DETERMINISM, false);
                    if (prop != null) {
                        usedModel = true;
                        // set model property
                        context.setDeterminismLevel(Determinism.valueOf(prop.toUpperCase()));
                    }
                }
                continue;
            }
            context.setDeterminismLevel(Determinism.valueOf(specificProp.toUpperCase()));
        }
    }
    ConnectorManagerRepository cmr = workItem.getDqpWorkContext().getVDB().getAttachment(ConnectorManagerRepository.class);
    ConnectorManager connectorManager = cmr.getConnectorManager(aqr.getConnectorName());
    if (connectorManager == null) {
        // can happen if sources are removed
        if (RelationalNodeUtil.hasOutputParams(command)) {
            // $NON-NLS-1$
            throw new AssertionError("A source is required to execute a procedure returning parameters");
        }
        // $NON-NLS-1$ //$NON-NLS-2$
        LogManager.logDetail(LogConstants.CTX_DQP, "source", aqr.getConnectorName(), "no longer exists, returning dummy results");
        return CollectionTupleSource.createNullTupleSource();
    }
    ConnectorWork work = connectorManager.registerRequest(aqr);
    if (!work.isForkable()) {
        aqr.setSerial(true);
    }
    CacheID cid = null;
    CacheDirective cd = null;
    if (workItem.getRsCache() != null && command.areResultsCachable()) {
        CachableVisitor cv = new CachableVisitor();
        PreOrPostOrderNavigator.doVisit(command, cv, PreOrPostOrderNavigator.PRE_ORDER, true);
        if (cv.cacheable) {
            try {
                cd = work.getCacheDirective();
            } catch (TranslatorException e) {
                // $NON-NLS-1$
                throw new TeiidProcessingException(QueryPlugin.Event.TEIID30504, e, aqr.getConnectorName() + ": " + e.getMessage());
            }
            if (cd != null) {
                if (cd.getScope() == Scope.NONE) {
                    parameterObject.doNotCache = true;
                } else {
                    String cmdString = command.toString();
                    if (cmdString.length() < 100000) {
                        // TODO: this check won't be needed if keys aren't exclusively held in memory
                        cid = new CacheID(workItem.getDqpWorkContext(), ParseInfo.DEFAULT_INSTANCE, cmdString);
                        cid.setParameters(cv.parameters);
                        if (cd.getInvalidation() == null || cd.getInvalidation() == Invalidation.NONE) {
                            CachedResults cr = workItem.getRsCache().get(cid);
                            if (cr != null && (cr.getRowLimit() == 0 || (parameterObject.limit > 0 && cr.getRowLimit() >= parameterObject.limit))) {
                                parameterObject.doNotCache = true;
                                // $NON-NLS-1$
                                LogManager.logDetail(LogConstants.CTX_DQP, "Using cache entry for", cid);
                                work.close();
                                return cr.getResults().createIndexedTupleSource();
                            }
                        } else if (cd.getInvalidation() == Invalidation.IMMEDIATE) {
                            workItem.getRsCache().remove(cid, CachingTupleSource.getDeterminismLevel(cd.getScope()));
                        }
                    }
                }
            } else {
                // $NON-NLS-1$
                LogManager.logTrace(LogConstants.CTX_DQP, aqr.getAtomicRequestID(), "no cache directive");
            }
        } else {
            // $NON-NLS-1$
            LogManager.logTrace(LogConstants.CTX_DQP, aqr.getAtomicRequestID(), "command not cachable");
        }
    }
    DataTierTupleSource dtts = new DataTierTupleSource(aqr, workItem, work, this, parameterObject.limit);
    TupleSource result = dtts;
    TupleBuffer tb = null;
    if (cid != null) {
        tb = getBufferManager().createTupleBuffer(aqr.getCommand().getProjectedSymbols(), aqr.getCommandContext().getConnectionId(), TupleSourceType.PROCESSOR);
        result = new CachingTupleSource(this, tb, (DataTierTupleSource) result, cid, parameterObject, cd, accessedGroups, workItem);
    }
    if (work.isThreadBound()) {
        result = handleThreadBound(workItem, aqr, work, cid, result, dtts, tb);
    } else if (!aqr.isSerial()) {
        dtts.addWork();
    }
    return result;
}
Also used : CachableVisitor(org.teiid.dqp.internal.process.TupleSourceCache.CachableVisitor) ConnectorManagerRepository(org.teiid.dqp.internal.datamgr.ConnectorManagerRepository) TempMetadataID(org.teiid.query.metadata.TempMetadataID) TupleBuffer(org.teiid.common.buffer.TupleBuffer) ConnectorManager(org.teiid.dqp.internal.datamgr.ConnectorManager) TeiidProcessingException(org.teiid.core.TeiidProcessingException) CacheDirective(org.teiid.translator.CacheDirective) CacheID(org.teiid.dqp.internal.process.SessionAwareCache.CacheID) CopyOnReadTupleSource(org.teiid.dqp.internal.process.TupleSourceCache.CopyOnReadTupleSource) TupleSource(org.teiid.common.buffer.TupleSource) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) GroupSymbol(org.teiid.query.sql.symbol.GroupSymbol) TranslatorException(org.teiid.translator.TranslatorException) QueryMetadataInterface(org.teiid.query.metadata.QueryMetadataInterface) ConnectorWork(org.teiid.dqp.internal.datamgr.ConnectorWork) AtomicRequestMessage(org.teiid.dqp.message.AtomicRequestMessage)

Example 24 with TupleBuffer

use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.

the class DataTierManagerImpl method handleThreadBound.

/**
 * thread bound work is tricky for our execution model
 *
 * the strategy here is that
 *
 * - if the result is not already a copying tuplesource (from caching)
 * then wrap in a copying tuple source
 *
 * - submit a workitem that will pull the results/fill the buffer,
 *
 * - return a tuplesource off of the buffer for use by the caller
 */
private TupleSource handleThreadBound(final RequestWorkItem workItem, AtomicRequestMessage aqr, ConnectorWork work, CacheID cid, TupleSource result, DataTierTupleSource dtts, TupleBuffer tb) throws AssertionError, TeiidComponentException, TeiidProcessingException {
    if (workItem.useCallingThread) {
        // in any case we want the underlying work done in the thread accessing the connectorworkitem
        aqr.setSerial(true);
        // simple case, just rely on the client using the same thread
        return result;
    }
    if (tb == null) {
        tb = getBufferManager().createTupleBuffer(aqr.getCommand().getProjectedSymbols(), aqr.getCommandContext().getConnectionId(), TupleSourceType.PROCESSOR);
    }
    final TupleSource ts = tb.createIndexedTupleSource(cid == null);
    if (cid == null) {
        result = new CopyOnReadTupleSource(tb, result) {

            @Override
            public void closeSource() {
                ts.closeSource();
            }
        };
    }
    final ThreadBoundTask callable = new ThreadBoundTask(workItem, result, dtts);
    // but we do so lazily just in case the results aren't needed
    if (aqr.isSerial()) {
        return new TupleSource() {

            boolean processed = false;

            @Override
            public List<?> nextTuple() throws TeiidComponentException, TeiidProcessingException {
                if (!processed) {
                    callable.call();
                    callable.onCompletion(null);
                    processed = true;
                }
                return ts.nextTuple();
            }

            @Override
            public void closeSource() {
                if (!processed) {
                    callable.onCompletion(null);
                    processed = true;
                }
                ts.closeSource();
            }
        };
    }
    aqr.setSerial(true);
    final FutureWork<Void> future = workItem.addWork(callable, callable, 100);
    final TupleBuffer buffer = tb;
    // return a thread-safe TupleSource
    return new TupleSource() {

        boolean checkedDone;

        @Override
        public List<?> nextTuple() throws TeiidComponentException, TeiidProcessingException {
            // TODO: could refactor as completion listener
            if (!checkedDone && future.isDone()) {
                checkedDone = true;
                try {
                    future.get();
                } catch (InterruptedException e) {
                    throw new TeiidComponentException(e);
                } catch (ExecutionException e) {
                    if (e.getCause() instanceof TeiidComponentException) {
                        throw (TeiidComponentException) e.getCause();
                    }
                    if (e.getCause() instanceof TeiidProcessingException) {
                        throw (TeiidProcessingException) e.getCause();
                    }
                    throw new TeiidComponentException(e);
                }
            }
            synchronized (buffer) {
                return ts.nextTuple();
            }
        }

        @Override
        public void closeSource() {
            synchronized (buffer) {
                ts.closeSource();
            }
            callable.done.set(true);
        }
    };
}
Also used : CopyOnReadTupleSource(org.teiid.dqp.internal.process.TupleSourceCache.CopyOnReadTupleSource) TupleSource(org.teiid.common.buffer.TupleSource) CollectionTupleSource(org.teiid.query.processor.CollectionTupleSource) TupleBuffer(org.teiid.common.buffer.TupleBuffer) CopyOnReadTupleSource(org.teiid.dqp.internal.process.TupleSourceCache.CopyOnReadTupleSource) TeiidComponentException(org.teiid.core.TeiidComponentException) ExecutionException(java.util.concurrent.ExecutionException) TeiidProcessingException(org.teiid.core.TeiidProcessingException)

Example 25 with TupleBuffer

use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.

the class SortNode method getBufferDirect.

@Override
public TupleBuffer getBufferDirect(int maxRows) throws BlockedException, TeiidComponentException, TeiidProcessingException {
    if (this.isClosed()) {
        // $NON-NLS-1$
        throw new AssertionError("called after close");
    }
    this.rowLimit = maxRows;
    if (this.output == null) {
        sortPhase();
    }
    usingOutput = true;
    TupleBuffer result = this.output;
    if (this.output.isFinal()) {
        this.output = null;
        close();
    }
    return result;
}
Also used : TupleBuffer(org.teiid.common.buffer.TupleBuffer)

Aggregations

TupleBuffer (org.teiid.common.buffer.TupleBuffer)43 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)19 BufferManager (org.teiid.common.buffer.BufferManager)16 List (java.util.List)15 Test (org.junit.Test)15 ArrayList (java.util.ArrayList)11 BlockedException (org.teiid.common.buffer.BlockedException)10 TupleSource (org.teiid.common.buffer.TupleSource)10 CommandContext (org.teiid.query.util.CommandContext)7 TeiidProcessingException (org.teiid.core.TeiidProcessingException)6 FakeRelationalNode (org.teiid.query.processor.relational.FakeRelationalNode)6 TeiidComponentException (org.teiid.core.TeiidComponentException)5 TupleBatch (org.teiid.common.buffer.TupleBatch)4 Map (java.util.Map)3 CollectionTupleSource (org.teiid.query.processor.CollectionTupleSource)3 Expression (org.teiid.query.sql.symbol.Expression)3 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedList (java.util.LinkedList)2 IndexedTupleSource (org.teiid.common.buffer.IndexedTupleSource)2