Search in sources :

Example 1 with ResizingArrayList

use of org.teiid.client.ResizingArrayList in project teiid by teiid.

the class RequestWorkItem method sendResultsIfNeeded.

/**
 * Send results if they have been requested.  This should only be called from the processing thread.
 */
protected boolean sendResultsIfNeeded(TupleBatch batch) throws TeiidComponentException, TeiidProcessingException {
    ResultsMessage response = null;
    ResultsReceiver<ResultsMessage> receiver = null;
    boolean result = true;
    synchronized (this) {
        if (this.resultsReceiver == null) {
            if (cursorRequestExpected()) {
                if (batch != null) {
                    // $NON-NLS-1$
                    throw new AssertionError("batch has no handler");
                }
                // $NON-NLS-1$
                throw BlockedException.block(requestID, "Blocking until client is ready");
            }
            return result;
        }
        if (!this.requestMsg.getRequestOptions().isContinuous()) {
            if ((this.begin > (batch != null ? batch.getEndRow() : this.resultsBuffer.getRowCount()) && !doneProducingBatches) || (this.transactionState == TransactionState.ACTIVE) || (returnsUpdateCount && !doneProducingBatches)) {
                return result;
            }
            if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
                // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                LogManager.logDetail(LogConstants.CTX_DQP, "[RequestWorkItem.sendResultsIfNeeded] requestID:", requestID, "resultsID:", this.resultsBuffer, "done:", doneProducingBatches);
            }
            boolean fromBuffer = false;
            int count = this.end - this.begin + 1;
            if (returnsUpdateCount) {
                count = Integer.MAX_VALUE;
            }
            if (batch == null || !(batch.containsRow(this.begin) || (batch.getTerminationFlag() && batch.getEndRow() <= this.begin))) {
                if (savedBatch != null && savedBatch.containsRow(this.begin)) {
                    batch = savedBatch;
                } else {
                    batch = resultsBuffer.getBatch(begin);
                    // fetch more than 1 batch from the buffer
                    boolean first = true;
                    int rowSize = resultsBuffer.getRowSizeEstimate();
                    int batches = CLIENT_FETCH_MAX_BATCHES;
                    if (rowSize > 0) {
                        int totalSize = rowSize * resultsBuffer.getBatchSize();
                        if (schemaSize == 0) {
                            schemaSize = this.dqpCore.getBufferManager().getSchemaSize(this.originalCommand.getProjectedSymbols());
                        }
                        int multiplier = schemaSize / totalSize;
                        if (multiplier > 1) {
                            batches *= multiplier;
                        }
                    }
                    if (returnsUpdateCount) {
                        batches = Integer.MAX_VALUE;
                    }
                    for (int i = 1; i < batches && batch.getRowCount() + resultsBuffer.getBatchSize() <= count && !batch.getTerminationFlag(); i++) {
                        TupleBatch next = resultsBuffer.getBatch(batch.getEndRow() + 1);
                        if (next.getRowCount() == 0) {
                            break;
                        }
                        if (first) {
                            first = false;
                            TupleBatch old = batch;
                            batch = new TupleBatch(batch.getBeginRow(), new ResizingArrayList<List<?>>(batch.getTuples()));
                            batch.setTermination(old.getTermination());
                        }
                        batch.getTuples().addAll(next.getTuples());
                        batch.setTermination(next.getTermination());
                    }
                }
                savedBatch = null;
                fromBuffer = true;
            }
            if (batch.getRowCount() > count) {
                long beginRow = isForwardOnly() ? begin : Math.min(this.begin, batch.getEndRow() - count + 1);
                long endRow = Math.min(beginRow + count - 1, batch.getEndRow());
                boolean last = false;
                if (endRow == batch.getEndRow()) {
                    last = batch.getTerminationFlag();
                } else if (isForwardOnly()) {
                    savedBatch = batch;
                }
                List<List<?>> memoryRows = batch.getTuples();
                batch = new TupleBatch(beginRow, memoryRows.subList((int) (beginRow - batch.getBeginRow()), (int) (endRow - batch.getBeginRow() + 1)));
                batch.setTerminationFlag(last);
            } else if (!fromBuffer) {
                result = !isForwardOnly();
            }
        } else if (batch == null) {
            return result;
        } else {
            result = false;
        }
        long finalRowCount = (this.resultsBuffer.isFinal() && !this.requestMsg.getRequestOptions().isContinuous()) ? this.resultsBuffer.getRowCount() : (batch.getTerminationFlag() ? batch.getEndRow() : -1);
        if (batch.getBeginRow() > Integer.MAX_VALUE || batch.getEndRow() > Integer.MAX_VALUE) {
            throw new TeiidProcessingException(QueryPlugin.Event.TEIID31174, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31174));
        }
        response = createResultsMessage(batch.getTuples(), this.originalCommand.getProjectedSymbols());
        response.setFirstRow((int) batch.getBeginRow());
        if (batch.getTermination() == TupleBatch.ITERATION_TERMINATED) {
            response.setLastRow((int) batch.getEndRow() - 1);
        } else {
            response.setLastRow((int) batch.getEndRow());
        }
        response.setUpdateResult(this.returnsUpdateCount);
        if (this.returnsUpdateCount) {
            // batch updates can have special exceptions in addition to update count results
            Throwable t = this.processor.getContext().getBatchUpdateException();
            if (t != null) {
                t = logError(t);
                response.setException(t);
            }
            // swap the result for the generated keys
            if (this.processor.getContext().isReturnAutoGeneratedKeys() && finalRowCount == 1 && this.processor.getContext().getGeneratedKeys() != null && handleGeneratedKeys(response)) {
                finalRowCount = response.getLastRow();
            } else if (finalRowCount == 0 && response.getException() == null) {
                // anon block or other construct not setting an explicit update count
                response.setResults(Arrays.asList(Arrays.asList(0)));
                finalRowCount = 1;
            }
        }
        // set final row
        response.setFinalRow((int) Math.min(finalRowCount, Integer.MAX_VALUE));
        if (response.getLastRow() == finalRowCount) {
            response.setDelayDeserialization(false);
        }
        setWarnings(response);
        // If it is stored procedure, set parameters
        if (originalCommand instanceof StoredProcedure) {
            StoredProcedure proc = (StoredProcedure) originalCommand;
            if (proc.returnParameters()) {
                response.setParameters(getParameterInfo(proc));
            }
        }
        /*
	         * mark the results sent at this point.
	         * communication exceptions will be treated as non-recoverable 
	         */
        receiver = this.resultsReceiver;
        this.resultsReceiver = null;
    }
    cancelCancelTask();
    if ((!this.dqpWorkContext.getSession().isEmbedded() && requestMsg.isDelaySerialization() && this.requestMsg.getShowPlan() == ShowPlan.ON) || this.requestMsg.getShowPlan() == ShowPlan.DEBUG || LogManager.isMessageToBeRecorded(LogConstants.CTX_COMMANDLOGGING, MessageLevel.TRACE)) {
        int bytes;
        try {
            boolean keep = !this.dqpWorkContext.getSession().isEmbedded() && requestMsg.isDelaySerialization();
            bytes = response.serialize(keep);
            if (keep) {
                response.setDelayDeserialization(true);
            }
            dataBytes.addAndGet(bytes);
            // $NON-NLS-1$ //$NON-NLS-2$
            LogManager.logDetail(// $NON-NLS-1$ //$NON-NLS-2$
            LogConstants.CTX_DQP, // $NON-NLS-1$ //$NON-NLS-2$
            "Sending results for", // $NON-NLS-1$ //$NON-NLS-2$
            requestID, // $NON-NLS-1$ //$NON-NLS-2$
            "start row", response.getFirstRow(), "end row", response.getLastRow(), bytes, // $NON-NLS-1$ //$NON-NLS-2$
            "bytes");
        } catch (Exception e) {
        // do nothing.  there is a low level serialization error that we will let happen
        // later since it would be inconvenient here
        }
    }
    setAnalysisRecords(response);
    receiver.receiveResults(response);
    return result;
}
Also used : ResultsMessage(org.teiid.client.ResultsMessage) CacheHint(org.teiid.query.sql.lang.CacheHint) TeiidComponentException(org.teiid.core.TeiidComponentException) QueryMetadataException(org.teiid.api.exception.query.QueryMetadataException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) TeiidException(org.teiid.core.TeiidException) BlockedException(org.teiid.common.buffer.BlockedException) XATransactionException(org.teiid.client.xa.XATransactionException) ExpiredTimeSliceException(org.teiid.query.processor.QueryProcessor.ExpiredTimeSliceException) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) StoredProcedure(org.teiid.query.sql.lang.StoredProcedure) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ResizingArrayList(org.teiid.client.ResizingArrayList) ResizingArrayList(org.teiid.client.ResizingArrayList) TupleBatch(org.teiid.common.buffer.TupleBatch)

Example 2 with ResizingArrayList

use of org.teiid.client.ResizingArrayList in project teiid by teiid.

the class ConnectorWorkItem method handleBatch.

protected AtomicResultsMessage handleBatch() throws TranslatorException {
    Assertion.assertTrue(!this.lastBatch);
    // $NON-NLS-1$
    LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.id, "Getting results from connector" });
    int batchSize = 0;
    List<List<?>> rows = new ResizingArrayList<List<?>>(batchSize / 4);
    try {
        while (batchSize < this.requestMsg.getFetchSize()) {
            List<?> row = this.execution.next();
            if (row == null) {
                this.lastBatch = true;
                break;
            }
            if (row.size() != this.expectedColumns) {
                // $NON-NLS-1$ //$NON-NLS-2$
                throw new AssertionError("Inproper results returned.  Expected " + this.expectedColumns + " columns, but was " + row.size());
            }
            try {
                try {
                    if (unmodifiableList) {
                        row = new ArrayList<Object>(row);
                    }
                    row = correctTypes(row);
                } catch (UnsupportedOperationException | ArrayStoreException e) {
                    // the translator should be modifiable, but we should be lax
                    if (unmodifiableList) {
                        throw e;
                    }
                    unmodifiableList = true;
                    row = new ArrayList<Object>(row);
                    row = correctTypes(row);
                }
            } catch (TeiidException e) {
                conversionError = e;
                break;
            }
            if (this.procedureBatchHandler != null) {
                row = this.procedureBatchHandler.padRow(row);
            }
            this.rowCount += 1;
            batchSize++;
            rows.add(row);
            // Check for max result rows exceeded
            if (this.requestMsg.getMaxResultRows() > -1 && this.rowCount >= this.requestMsg.getMaxResultRows()) {
                if (this.rowCount == this.requestMsg.getMaxResultRows() && !this.requestMsg.isExceptionOnMaxRows()) {
                    // $NON-NLS-1$
                    LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.id, "Exceeded max, returning", this.requestMsg.getMaxResultRows() });
                    this.lastBatch = true;
                    break;
                } else if (this.rowCount > this.requestMsg.getMaxResultRows() && this.requestMsg.isExceptionOnMaxRows()) {
                    // $NON-NLS-1$
                    String msg = QueryPlugin.Util.getString("ConnectorWorker.MaxResultRowsExceed", this.requestMsg.getMaxResultRows());
                    throw new TranslatorException(QueryPlugin.Event.TEIID30478, msg);
                }
            }
        }
    } catch (DataNotAvailableException e) {
        if (rows.size() == 0) {
            throw e;
        }
        if (e.getWaitUntil() != null) {
            // we have an await until that we need to enforce
            this.dnae = e;
        }
    // else we can just ignore the delay
    }
    if (lastBatch) {
        if (this.procedureBatchHandler != null) {
            List<?> row = this.procedureBatchHandler.getParameterRow();
            if (row != null) {
                try {
                    row = correctTypes(row);
                    rows.add(row);
                    this.rowCount += 1;
                } catch (TeiidException e) {
                    lastBatch = false;
                    conversionError = e;
                }
            }
        }
        // $NON-NLS-1$\
        LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.id, "Obtained last batch, total row count:", rowCount });
    } else {
        // $NON-NLS-1$
        LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.id, "Obtained results from connector, current row count:", rowCount });
    }
    int currentRowCount = rows.size();
    if (!lastBatch && currentRowCount == 0) {
        // Defect 13366 - Should send all batches, even if they're zero size.
        // Log warning if received a zero-size non-last batch from the connector.
        LogManager.logWarning(LogConstants.CTX_CONNECTOR, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30004, requestMsg.getConnectorName()));
    }
    AtomicResultsMessage response = createResultsMessage(rows.toArray(new List[currentRowCount]));
    // if we need to keep the execution alive, then we can not support implicit close.
    response.setSupportsImplicitClose(!this.securityContext.keepExecutionAlive() && !explicitClose);
    response.setWarnings(this.securityContext.getWarnings());
    if (this.securityContext.getCacheDirective() != null) {
        response.setScope(this.securityContext.getCacheDirective().getScope());
    }
    if (this.securityContext.getScope() != null && (response.getScope() == null || response.getScope().compareTo(this.securityContext.getScope()) > 0)) {
        response.setScope(this.securityContext.getScope());
    }
    if (lastBatch) {
        response.setFinalRow(rowCount);
    }
    return response;
}
Also used : ArrayList(java.util.ArrayList) ResizingArrayList(org.teiid.client.ResizingArrayList) SourceHint(org.teiid.query.sql.lang.SourceHint) SpecificHint(org.teiid.query.sql.lang.SourceHint.SpecificHint) TeiidException(org.teiid.core.TeiidException) List(java.util.List) ArrayList(java.util.ArrayList) ResizingArrayList(org.teiid.client.ResizingArrayList) AtomicResultsMessage(org.teiid.dqp.message.AtomicResultsMessage) ResizingArrayList(org.teiid.client.ResizingArrayList)

Example 3 with ResizingArrayList

use of org.teiid.client.ResizingArrayList in project teiid by teiid.

the class SPage method clone.

public SPage clone(STree tree) {
    try {
        if (this.managedBatch != null && trackingObject == null) {
            this.trackingObject = new Object();
            CleanupReference managedBatchReference = new CleanupReference(trackingObject, managedBatch, stree.getBatchManager(children == null).getBatchManagerReference());
            REFERENCES.put(managedBatch, managedBatchReference);
        }
        SPage clone = (SPage) super.clone();
        clone.stree = tree;
        if (children != null) {
            clone.children = new ResizingArrayList<SPage>(children);
        }
        if (values != null) {
            clone.values = new ResizingArrayList<List<?>>(values);
        }
        return clone;
    } catch (CloneNotSupportedException e) {
        throw new TeiidRuntimeException(QueryPlugin.Event.TEIID30038, e);
    }
}
Also used : List(java.util.List) ResizingArrayList(org.teiid.client.ResizingArrayList) LinkedList(java.util.LinkedList) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException)

Aggregations

List (java.util.List)3 ResizingArrayList (org.teiid.client.ResizingArrayList)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 TeiidException (org.teiid.core.TeiidException)2 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)2 QueryMetadataException (org.teiid.api.exception.query.QueryMetadataException)1 ResultsMessage (org.teiid.client.ResultsMessage)1 XATransactionException (org.teiid.client.xa.XATransactionException)1 BlockedException (org.teiid.common.buffer.BlockedException)1 TupleBatch (org.teiid.common.buffer.TupleBatch)1 TeiidComponentException (org.teiid.core.TeiidComponentException)1 TeiidProcessingException (org.teiid.core.TeiidProcessingException)1 AtomicResultsMessage (org.teiid.dqp.message.AtomicResultsMessage)1 ExpiredTimeSliceException (org.teiid.query.processor.QueryProcessor.ExpiredTimeSliceException)1 CacheHint (org.teiid.query.sql.lang.CacheHint)1 SourceHint (org.teiid.query.sql.lang.SourceHint)1 SpecificHint (org.teiid.query.sql.lang.SourceHint.SpecificHint)1 StoredProcedure (org.teiid.query.sql.lang.StoredProcedure)1