Search in sources :

Example 6 with TupleBuffer

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

the class WindowFunctionProjectNode method buildResults.

/**
 * Build the results by maintaining indexes that either map
 * rowid->values
 * or
 * rowid->partitionid and partitionid->values
 *
 * TODO use the size hint for tree balancing
 */
private void buildResults() throws TeiidComponentException, TeiidProcessingException, FunctionExecutionException, ExpressionEvaluationException {
    List<Map.Entry<WindowSpecification, WindowSpecificationInfo>> specs = new ArrayList<Map.Entry<WindowSpecification, WindowSpecificationInfo>>(windows.entrySet());
    for (int specIndex = 0; specIndex < specs.size(); specIndex++) {
        Map.Entry<WindowSpecification, WindowSpecificationInfo> entry = specs.get(specIndex);
        WindowSpecificationInfo info = entry.getValue();
        IndexedTupleSource specificationTs = tb.createIndexedTupleSource();
        boolean multiGroup = false;
        int[] partitionIndexes = null;
        int[] orderIndexes = null;
        // if there is partitioning or ordering, then sort
        if (!info.orderType.isEmpty()) {
            multiGroup = true;
            int[] sortKeys = new int[info.orderType.size()];
            int i = 0;
            if (!info.groupIndexes.isEmpty()) {
                for (Integer sortIndex : info.groupIndexes) {
                    sortKeys[i++] = sortIndex;
                }
                partitionIndexes = Arrays.copyOf(sortKeys, info.groupIndexes.size());
            }
            if (!info.sortIndexes.isEmpty()) {
                for (Integer sortIndex : info.sortIndexes) {
                    sortKeys[i++] = sortIndex;
                }
                orderIndexes = Arrays.copyOfRange(sortKeys, info.groupIndexes.size(), info.groupIndexes.size() + info.sortIndexes.size());
            }
            if (!info.functions.isEmpty()) {
                // $NON-NLS-1$
                ElementSymbol key = new ElementSymbol("rowId");
                key.setType(DataTypeManager.DefaultDataClasses.INTEGER);
                // $NON-NLS-1$
                ElementSymbol value = new ElementSymbol("partitionId");
                value.setType(DataTypeManager.DefaultDataClasses.INTEGER);
                List<ElementSymbol> elements = Arrays.asList(key, value);
                partitionMapping[specIndex] = this.getBufferManager().createSTree(elements, this.getConnectionID(), 1);
            }
            SortUtility su = new SortUtility(null, Mode.SORT, this.getBufferManager(), this.getConnectionID(), tb.getSchema(), info.orderType, info.nullOrderings, sortKeys);
            su.setWorkingBuffer(tb);
            su.setNonBlocking(true);
            TupleBuffer sorted = su.sort();
            specificationTs = sorted.createIndexedTupleSource(true);
        }
        List<AggregateFunction> aggs = initializeAccumulators(info.functions, specIndex, false);
        List<AggregateFunction> rowValueAggs = initializeAccumulators(info.rowValuefunctions, specIndex, true);
        int groupId = 0;
        List<?> lastRow = null;
        while (specificationTs.hasNext()) {
            List<?> tuple = specificationTs.nextTuple();
            if (multiGroup) {
                if (lastRow != null) {
                    boolean samePartition = GroupingNode.sameGroup(partitionIndexes, tuple, lastRow) == -1;
                    if (!aggs.isEmpty() && (!samePartition || GroupingNode.sameGroup(orderIndexes, tuple, lastRow) != -1)) {
                        saveValues(specIndex, aggs, groupId, samePartition, false);
                        groupId++;
                    }
                    saveValues(specIndex, rowValueAggs, lastRow.get(lastRow.size() - 1), samePartition, true);
                }
                if (!aggs.isEmpty()) {
                    List<Object> partitionTuple = Arrays.asList(tuple.get(tuple.size() - 1), groupId);
                    partitionMapping[specIndex].insert(partitionTuple, InsertMode.NEW, -1);
                }
            }
            for (AggregateFunction function : aggs) {
                function.addInput(tuple, getContext());
            }
            for (AggregateFunction function : rowValueAggs) {
                function.addInput(tuple, getContext());
            }
            lastRow = tuple;
        }
        if (lastRow != null) {
            saveValues(specIndex, aggs, groupId, true, false);
            saveValues(specIndex, rowValueAggs, lastRow.get(lastRow.size() - 1), true, true);
        }
    }
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) ArrayList(java.util.ArrayList) TupleBuffer(org.teiid.common.buffer.TupleBuffer) WindowSpecification(org.teiid.query.sql.symbol.WindowSpecification) IndexedTupleSource(org.teiid.common.buffer.IndexedTupleSource) AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) LanguageObject(org.teiid.query.sql.LanguageObject) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Example 7 with TupleBuffer

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

the class AccessNode method nextCommand.

@SuppressWarnings("unused")
protected Command nextCommand() throws TeiidProcessingException, TeiidComponentException {
    // to ensure that the subquery ids remain stable
    if (nextCommand == null) {
        nextCommand = (Command) processingCommand.clone();
        if (evaluatedPlans != null) {
            for (WithQueryCommand with : ((QueryCommand) nextCommand).getWith()) {
                TupleBuffer tb = evaluatedPlans.get(with.getGroupSymbol()).collector.getTupleBuffer();
                with.setTupleBuffer(tb);
            }
        }
    }
    return nextCommand;
}
Also used : TupleBuffer(org.teiid.common.buffer.TupleBuffer) QueryCommand(org.teiid.query.sql.lang.QueryCommand) WithQueryCommand(org.teiid.query.sql.lang.WithQueryCommand) WithQueryCommand(org.teiid.query.sql.lang.WithQueryCommand)

Example 8 with TupleBuffer

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

the class JoinNode method nextBatchDirectInternal.

/**
 * @see org.teiid.query.processor.relational.RelationalNode#nextBatchDirect()
 * @since 4.2
 */
protected TupleBatch nextBatchDirectInternal() throws BlockedException, TeiidComponentException, TeiidProcessingException {
    try {
        if (state == State.LOAD_LEFT) {
            boolean rightDep = false;
            // dependent semi joins are processed right first
            if (isDependent() && (this.joinType == JoinType.JOIN_ANTI_SEMI || this.joinType == JoinType.JOIN_SEMI)) {
                rightDep = true;
                this.joinStrategy.openRight();
                this.joinStrategy.loadRight();
                TupleBuffer buffer = this.joinStrategy.rightSource.getTupleBuffer();
                // the tuplebuffer may be from a lower node, so pass in the schema
                dvs = new DependentValueSource(buffer, this.joinStrategy.rightSource.getSource().getElements());
                dvs.setDistinct(this.joinStrategy.rightSource.isExpresssionDistinct());
                this.getContext().getVariableContext().setGlobalValue(this.dependentValueSource, dvs);
            }
            if (this.joinType != JoinType.JOIN_FULL_OUTER || this.getJoinCriteria() == null) {
                this.joinStrategy.leftSource.setImplicitBuffer(ImplicitBuffer.NONE);
            }
            this.joinStrategy.openLeft();
            this.joinStrategy.loadLeft();
            if (isDependent() && !rightDep) {
                TupleBuffer buffer = this.joinStrategy.leftSource.getTupleBuffer();
                // the tuplebuffer may be from a lower node, so pass in the schema
                dvs = new DependentValueSource(buffer, this.joinStrategy.leftSource.getSource().getElements());
                dvs.setDistinct(this.joinStrategy.leftSource.isExpresssionDistinct());
                this.getContext().getVariableContext().setGlobalValue(this.dependentValueSource, dvs);
            }
            state = State.LOAD_RIGHT;
        }
    } catch (BlockedException e) {
        if (!isDependent()) {
            if (getJoinType() != JoinType.JOIN_FULL_OUTER && this.joinStrategy.leftSource.getSortUtility() == null && this.joinStrategy.leftSource.rowCountLE(0)) {
                this.terminateBatches();
                return pullBatch();
            }
            this.joinStrategy.openRight();
            this.joinStrategy.loadRight();
            prefetch(this.joinStrategy.rightSource, this.joinStrategy.leftSource);
        }
        throw e;
    }
    try {
        if (state == State.LOAD_RIGHT) {
            if (getJoinType() != JoinType.JOIN_FULL_OUTER && this.joinStrategy.leftSource.getSortUtility() == null && this.joinStrategy.leftSource.rowCountLE(0)) {
                this.terminateBatches();
                return pullBatch();
            }
            this.joinStrategy.openRight();
            this.joinStrategy.loadRight();
            state = State.EXECUTE;
        }
        this.joinStrategy.process();
        this.terminateBatches();
    } catch (BatchAvailableException e) {
    // pull the batch
    } catch (BlockedException e) {
        // could track which side is blocking
        try {
            prefetch(this.joinStrategy.leftSource, this.joinStrategy.rightSource);
        } catch (BlockedException e1) {
        }
        prefetch(this.joinStrategy.rightSource, this.joinStrategy.leftSource);
        throw e;
    }
    return pullBatch();
}
Also used : TupleBuffer(org.teiid.common.buffer.TupleBuffer) BlockedException(org.teiid.common.buffer.BlockedException)

Example 9 with TupleBuffer

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

the class RelationalNode method getBuffer.

/**
 * return the final tuple buffer or null if not available
 * @return
 * @throws TeiidProcessingException
 * @throws TeiidComponentException
 * @throws BlockedException
 */
public final TupleBuffer getBuffer(int maxRows) throws BlockedException, TeiidComponentException, TeiidProcessingException {
    CommandContext context = this.getContext();
    if (context != null && context.isCancelled()) {
        throw new TeiidProcessingException(QueryPlugin.Event.TEIID30160, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30160, getContext().getRequestId()));
    }
    boolean recordStats = context != null && context.getCollectNodeStatistics() && !isLastBatch();
    try {
        // start timer for this batch
        if (recordStats) {
            this.getProcessingState().nodeStatistics.startBatchTimer();
        }
        TupleBuffer buffer = getBufferDirect(maxRows);
        terminateBatches();
        if (recordStats) {
            // stop timer for this batch (normal)
            this.getProcessingState().nodeStatistics.stopBatchTimer();
            this.getProcessingState().nodeStatistics.collectCumulativeNodeStats(buffer.getRowCount(), RelationalNodeStatistics.BATCHCOMPLETE_STOP);
            this.getProcessingState().nodeStatistics.collectNodeStats(this.getChildren());
            if (LogManager.isMessageToBeRecorded(org.teiid.logging.LogConstants.CTX_DQP, MessageLevel.TRACE) && !buffer.isForwardOnly()) {
                for (long i = 1; i <= buffer.getRowCount(); i += buffer.getBatchSize()) {
                    TupleBatch tb = buffer.getBatch(i);
                    recordBatch(tb);
                }
            }
            recordStats = false;
        }
        return buffer;
    } catch (BlockedException e) {
        if (recordStats) {
            // stop timer for this batch (BlockedException)
            this.getProcessingState().nodeStatistics.stopBatchTimer();
            this.getProcessingState().nodeStatistics.collectCumulativeNodeStats(null, RelationalNodeStatistics.BLOCKEDEXCEPTION_STOP);
            recordStats = false;
        }
        throw e;
    } finally {
        if (recordStats) {
            this.getProcessingState().nodeStatistics.stopBatchTimer();
        }
    }
}
Also used : CommandContext(org.teiid.query.util.CommandContext) TupleBuffer(org.teiid.common.buffer.TupleBuffer) BlockedException(org.teiid.common.buffer.BlockedException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) TupleBatch(org.teiid.common.buffer.TupleBatch)

Example 10 with TupleBuffer

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

the class BatchCollector method collectTuples.

public TupleBuffer collectTuples(boolean singleBatch) throws TeiidComponentException, TeiidProcessingException {
    TupleBatch batch = null;
    while (!done) {
        if (this.hasFinalBuffer) {
            if (this.buffer == null) {
                TupleBuffer finalBuffer = this.sourceNode.getBuffer(rowLimit);
                Assertion.isNotNull(finalBuffer);
                this.buffer = finalBuffer;
            }
            if (this.buffer.isFinal()) {
                this.buffer.setForwardOnly(forwardOnly);
                done = true;
                break;
            }
        }
        batch = sourceNode.nextBatch();
        if (rowLimit > 0 && rowLimit <= batch.getEndRow()) {
            if (!done) {
                this.sourceNode.close();
            }
            List<?> lastTuple = null;
            if (saveLastRow) {
                if (batch.getTerminationFlag()) {
                    lastTuple = batch.getTuples().get(batch.getTuples().size() - 1);
                } else if (rowLimit < batch.getBeginRow()) {
                    // skip until end
                    continue;
                }
            }
            boolean modified = false;
            if (rowLimit < batch.getEndRow()) {
                // we know row limit must be smaller than max int, so an int cast is safe here
                int firstRow = (int) Math.min(rowLimit + 1, batch.getBeginRow());
                List<List<?>> tuples = batch.getTuples().subList(0, rowLimit - firstRow + 1);
                batch = new TupleBatch(firstRow, tuples);
                modified = true;
            }
            if (lastTuple != null) {
                if (!modified) {
                    batch = new TupleBatch(batch.getBeginRow(), batch.getTuples());
                }
                batch.getTuples().add(lastTuple);
            }
            batch.setTerminationFlag(true);
        }
        flushBatch(batch);
        // Check for termination condition
        if (batch.getTerminationFlag()) {
            done = true;
            if (!this.sourceNode.hasBuffer()) {
                buffer.close();
            }
            break;
        }
        if (singleBatch) {
            return null;
        }
    }
    return buffer;
}
Also used : TupleBuffer(org.teiid.common.buffer.TupleBuffer) List(java.util.List) TupleBatch(org.teiid.common.buffer.TupleBatch)

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