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;
}
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;
}
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);
}
}
Aggregations