@Override protected synchronized TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException { evaluate(false); if (streaming) { while (state == State.BUILDING) { try { this.wait(); } catch (InterruptedException e) { throw new TeiidRuntimeException(QueryPlugin.Event.TEIID30169, e); } } unwrapException(asynchException); TupleBatch batch = this.buffer.getBatch(outputRow); outputRow = batch.getEndRow() + 1; if (state != State.DONE && !batch.getTerminationFlag()) { state = hasNextBatch() ? State.AVAILABLE : State.BUILDING; } return batch; } while (!isBatchFull() && !isLastBatch()) { if (item == null) { try { item = result.iter.next(); } catch (XPathException e) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID30170, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30170, e.getMessage())); } rowCount++; if (item == null) { terminateBatches(); break; } } addBatchRow(processRow()); if (rowCount == rowLimit) { terminateBatches(); break; } } return pullBatch(); }
private TupleBatch nextBatchDirect() throws BlockedException, TeiidProcessingException, TeiidComponentException { boolean done = false; TupleBatch result = null; try { init(); long currentTime = System.currentTimeMillis(); Assertion.assertTrue(!processorClosed); // TODO: see if there is pending work before preempting while (currentTime < context.getTimeSliceEnd() || context.isNonBlocking()) { if (requestCanceled) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID30160, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30160, getProcessID())); } if (currentTime > context.getTimeoutEnd()) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID30161, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30161)); } result = processPlan.nextBatch(); if (continuous) { result.setRowOffset(rowOffset); if (result.getTerminationFlag()) { result.setTermination(TupleBatch.ITERATION_TERMINATED); List<Object> terminationTuple = Arrays.asList(new Object[this.getOutputElements().size()]); result.getTuples().add(terminationTuple); this.context.getTupleSourceCache().close(); this.processPlan.close(); this.processPlan.reset(); this.context.incrementReuseCount(); this.open = false; } rowOffset = result.getEndRow() + 1; } if (result.getTermination() != TupleBatch.NOT_TERMINATED) { if (result.getTerminationFlag()) { done = true; } break; } if (result.getRowCount() > 0) { break; } } } catch (BlockedException e) { throw e; } catch (TeiidException e) { closeProcessing(); if (e instanceof TeiidProcessingException) { throw (TeiidProcessingException) e; } if (e instanceof TeiidComponentException) { throw (TeiidComponentException) e; } throw new TeiidComponentException(QueryPlugin.Event.TEIID30162, e); } if (done) { closeProcessing(); } if (result == null) { throw EXPIRED_TIME_SLICE; } return result; }
/** * Get batch from child node Walk through each row of child batch Bind values to insertCommand * Execute insertCommand Update insertCount When no more data is available, output batch with * single row containing insertCount */ public TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException { while (phase == REQUEST_CREATION) { checkExitConditions(); /* If we don't have a batch to work, get the next */ if (currentBatch == null) { if (sourceDone) { phase = RESPONSE_PROCESSING; break; } currentBatch = getChildren()[0].nextBatch(); // can throw BlockedException sourceDone = currentBatch.getTerminationFlag(); this.batchRow = currentBatch.getBeginRow(); // normally we would want to skip a 0 sized batch, but it typically represents the terminal // batch // and for implicit temp tables we need to issue an empty insert if (currentBatch.getRowCount() == 0 && (!currentBatch.getTerminationFlag() || mode != Mode.ITERATOR)) { currentBatch = null; continue; } } int batchSize = currentBatch.getRowCount(); int requests = 1; switch (mode) { case ITERATOR: if (buffer == null) { buffer = getBufferManager() .createTupleBuffer(intoElements, getConnectionID(), TupleSourceType.PROCESSOR); } buffer.addTupleBatch(currentBatch, true); if (currentBatch.getTerminationFlag() && (buffer.getRowCount() != 0 || intoGroup.isImplicitTempGroupSymbol())) { Insert insert = new Insert(intoGroup, intoElements, null); buffer.close(); insert.setTupleSource(buffer.createIndexedTupleSource(true)); // Register insert command against source registerRequest(insert); } else { requests = 0; } break; case BATCH: // Register batched update command against source int endRow = currentBatch.getEndRow(); List<Command> rows = new ArrayList<Command>(endRow - batchRow); for (int rowNum = batchRow; rowNum <= endRow; rowNum++) { Insert insert = new Insert( intoGroup, intoElements, convertValuesToConstants(currentBatch.getTuple(rowNum), intoElements)); rows.add(insert); } registerRequest(new BatchedUpdateCommand(rows)); break; case SINGLE: batchSize = 1; // Register insert command against source // Defect 16036 - submit a new INSERT command to the DataManager. registerRequest( new Insert( intoGroup, intoElements, convertValuesToConstants(currentBatch.getTuple(batchRow), intoElements))); } this.batchRow += batchSize; if (batchRow > currentBatch.getEndRow()) { currentBatch = null; } this.requestsRegistered += requests; } checkExitConditions(); // End this node's work addBatchRow(Arrays.asList(insertCount)); terminateBatches(); return pullBatch(); }