use of org.teiid.common.buffer.TupleBatch in project teiid by teiid.
the class UnionAllNode method nextBatchDirectInternal.
public TupleBatch nextBatchDirectInternal() throws BlockedException, TeiidComponentException, TeiidProcessingException {
// Walk through all children and for each one that isn't done, try to retrieve a batch
// When all sources are done, set the termination flag on that batch
RelationalNode[] children = getChildren();
int childCount = getChildCount();
int activeSources = 0;
TupleBatch batch = null;
boolean additionalSources = false;
for (int i = 0; i < childCount; i++) {
if (children[i] != null && !sourceDone[i]) {
if (sourceOpen != null && !sourceOpen[i]) {
additionalSources = true;
continue;
}
activeSources++;
if (batch == null) {
try {
batch = children[i].nextBatch();
// Got a batch
if (batch.getTerminationFlag() == true) {
// Mark source as being done and decrement the activeSources counter
sourceDone[i] = true;
activeSources--;
if (reserved > 0) {
getBufferManager().releaseBuffers(schemaSize);
reserved -= schemaSize;
}
}
} catch (BlockedException e) {
// no problem - try the next one
}
} else {
// This is sufficient to break the loop - we won't learn anything new after this
break;
}
}
}
// Determine what to return
TupleBatch outputBatch = null;
if (batch != null) {
// Rebuild the batch to reset the output row
outputBatch = new TupleBatch(outputRow, batch.getTuples());
// This is the last unioned batch if:
// 1) This batch is a termination batch from the child
// 2) No other active sources exist
outputBatch.setTerminationFlag(batch.getTerminationFlag() && activeSources == 0 && !additionalSources);
// Update output row for next batch
outputRow += outputBatch.getRowCount();
} else if (activeSources > 0) {
// $NON-NLS-1$
throw BlockedException.block(getContext().getRequestId(), "Blocking on union source.", getID());
} else {
boolean openedAny = false;
int toOpen = 0;
if (sourceOpen != null) {
for (int i = 0; i < childCount; i++) {
if (sourceOpen[i] && sourceDone[i]) {
toOpen++;
}
}
for (int i = 0; i < childCount && toOpen > 0; i++) {
if (!sourceOpen[i]) {
getBufferManager().reserveBuffers(schemaSize, BufferReserveMode.FORCE);
reserved += schemaSize;
children[i].open();
sourceOpen[i] = true;
openedAny = true;
toOpen--;
}
}
}
if (openedAny) {
return nextBatchDirect();
}
// No batch and no active sources - return empty termination batch (should never happen but just in case)
outputBatch = new TupleBatch(outputRow, Collections.EMPTY_LIST);
outputBatch.setTerminationFlag(true);
}
return outputBatch;
}
use of org.teiid.common.buffer.TupleBatch in project teiid by teiid.
the class PlanExecutionNode method nextBatchDirect.
public TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (!isOpen) {
if (!needsProcessing) {
while (true) {
if (prepareNextCommand()) {
needsProcessing = true;
break;
}
if (!hasNextCommand()) {
needsProcessing = false;
break;
}
}
}
if (needsProcessing) {
plan.open();
isOpen = true;
}
}
if (!needsProcessing) {
terminateBatches();
return pullBatch();
}
TupleBatch batch = plan.nextBatch();
for (List<?> tuple : batch.getTuples()) {
addBatchRow(tuple);
}
if (batch.getTerminationFlag()) {
if (hasNextCommand()) {
resetPlan();
} else {
terminateBatches();
}
}
return pullBatch();
}
use of org.teiid.common.buffer.TupleBatch in project teiid by teiid.
the class BatchedUpdatePlan method nextBatch.
/**
* @see org.teiid.query.processor.ProcessorPlan#nextBatch()
* @since 4.2
*/
public TupleBatch nextBatch() throws BlockedException, TeiidComponentException, TeiidProcessingException {
for (; planIndex < updatePlans.length && (getContext() == null || getContext().getBatchUpdateException() == null); ) {
try {
if (!planOpened[planIndex]) {
// Open the plan only once
/* Defect 16166
* Some commands in a batch may depend on updates by previous commands in the same batch. A call
* to open() usually submits an atomic command, so calling open() on all the child plans at the same time
* will mean that the datasource may not be in the state expected by a later command within the batch. So,
* for a batch of commands, we only open() a later plan when we are finished with the previous plan to
* guarantee that the commands in the previous plan are completed before the commands in any subsequent
* plans are executed.
*/
openPlan();
} else if (this.planContexts[planIndex] != null) {
this.getContext().getTransactionServer().resume(this.planContexts[planIndex]);
}
// Execute nextBatch() on each plan in sequence
TupleBatch nextBatch = null;
do {
// Can throw BlockedException
nextBatch = updatePlans[planIndex].nextBatch();
List<List<?>> currentBatch = nextBatch.getTuples();
for (int i = 0; i < currentBatch.size(); i++, commandIndex++) {
updateCounts[commandIndex] = currentBatch.get(i);
}
} while (!nextBatch.getTerminationFlag());
// since we are done with the plan explicitly close it.
updatePlans[planIndex].close();
if (this.planContexts[planIndex] != null) {
TransactionService ts = this.getContext().getTransactionServer();
ts.commit(this.planContexts[planIndex]);
this.planContexts[planIndex] = null;
}
planIndex++;
} catch (BlockedException e) {
throw e;
} catch (TeiidComponentException | TeiidProcessingException e) {
if (singleResult) {
throw e;
}
Throwable cause = e;
if (e.getCause() instanceof TranslatorBatchException) {
TranslatorBatchException tbe = (TranslatorBatchException) e.getCause();
for (int i = 0; i < tbe.getUpdateCounts().length; i++) {
updateCounts[commandIndex++] = Arrays.asList(tbe.getUpdateCounts()[i]);
}
}
updateCounts = Arrays.copyOf(updateCounts, commandIndex);
getContext().setBatchUpdateException(cause);
} finally {
if (planIndex < updatePlans.length && this.planContexts[planIndex] != null) {
this.getContext().getTransactionServer().suspend(this.planContexts[planIndex]);
}
}
}
if (singleResult) {
long result = 0;
for (int i = 0; i < updateCounts.length; i++) {
int value = (Integer) updateCounts[i].get(0);
if (value == Statement.EXECUTE_FAILED) {
// the batch results rather than throwing an exception
throw new TeiidProcessingException(QueryPlugin.Event.TEIID31199, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31198));
}
if (value > 0) {
result += value;
}
}
TupleBatch batch = new TupleBatch(1, new List<?>[] { Arrays.asList((int) Math.min(Integer.MAX_VALUE, result)) });
batch.setTerminationFlag(true);
return batch;
}
// Add tuples to current batch
TupleBatch batch = new TupleBatch(1, updateCounts);
batch.setTerminationFlag(true);
return batch;
}
use of org.teiid.common.buffer.TupleBatch in project teiid by teiid.
the class TestBatchIterator method testNoSaveForwardOnly.
@Test
public void testNoSaveForwardOnly() throws Exception {
BatchIterator bi = new BatchIterator(new FakeRelationalNode(1, new List[] { Arrays.asList(1), Arrays.asList(1), Arrays.asList(1), Arrays.asList(1) }, 2) {
@Override
public TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException {
TupleBatch tb = super.nextBatchDirect();
tb.setRowOffset(tb.getBeginRow() + 3);
return tb;
}
});
BufferManager bm = BufferManagerFactory.getStandaloneBufferManager();
TupleBuffer tb = bm.createTupleBuffer(Arrays.asList(new ElementSymbol("x", null, DataTypeManager.DefaultDataClasses.INTEGER)), "test", TupleSourceType.PROCESSOR);
tb.setForwardOnly(true);
// $NON-NLS-1$
bi.setBuffer(tb, false);
tb.addTuple(Arrays.asList(2));
tb.addTuple(Arrays.asList(2));
tb.addTuple(Arrays.asList(2));
assertEquals(3, bi.getBuffer().getManagedRowCount());
bi.nextTuple();
// pull the first batch
assertEquals(2, bi.available());
assertEquals(0, bi.getBuffer().getManagedRowCount());
for (int i = 0; i < 2; i++) {
assertNotNull(bi.nextTuple());
assertEquals(0, bi.getBuffer().getManagedRowCount());
}
bi.readAhead(3);
assertEquals(2, bi.getBuffer().getManagedRowCount());
for (int i = 0; i < 4; i++) {
assertNotNull(bi.nextTuple());
assertEquals(0, bi.getBuffer().getManagedRowCount());
}
assertNull(bi.nextTuple());
assertEquals(0, bi.getBuffer().getManagedRowCount());
}
use of org.teiid.common.buffer.TupleBatch in project teiid by teiid.
the class TestBatchedUpdatePlan method testCommandLevelTransaction.
@Test
public void testCommandLevelTransaction() throws Exception {
// $NON-NLS-1$
CommandContext context = new CommandContext("pID", null, null, null, 1);
context.setMetadata(RealMetadataFactory.example1Cached());
TransactionContext tc = new TransactionContext();
TransactionService ts = Mockito.mock(TransactionService.class);
context.setTransactionService(ts);
context.setTransactionContext(tc);
ProcessorPlan[] plans = new ProcessorPlan[4];
for (int i = 0; i < plans.length - 2; i++) {
plans[i] = new FakeProcessorPlan(1);
}
for (int i = 2; i < plans.length; i++) {
plans[i] = new FakeProcessorPlan(1) {
public Boolean requiresTransaction(boolean transactionalReads) {
return true;
}
};
}
BatchedUpdatePlan plan = new BatchedUpdatePlan(Arrays.asList(plans), plans.length, null, false);
plan.requiresTransaction(false);
plan.initialize(context, null, null);
plan.open();
TupleBatch batch = plan.nextBatch();
assertEquals(4, batch.getRowCount());
Mockito.verify(ts, Mockito.times(2)).begin(tc);
Mockito.verify(ts, Mockito.times(2)).commit(tc);
}
Aggregations