use of org.teiid.core.TeiidComponentException 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.core.TeiidComponentException in project teiid by teiid.
the class RequestWorkItem method processNew.
protected void processNew() throws TeiidProcessingException, TeiidComponentException {
planningStart = System.currentTimeMillis();
SessionAwareCache<CachedResults> rsCache = dqpCore.getRsCache();
boolean cachable = false;
CacheID cacheId = null;
if (rsCache != null) {
boolean canUseCache = true;
if (requestMsg.getRequestOptions().isContinuous()) {
canUseCache = false;
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Command is continuous, result set caching will not be used");
} else if (!requestMsg.useResultSetCache() && getCacheHint() == null) {
canUseCache = false;
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Command has no cache hint and result set cache mode is not on.");
}
if (canUseCache) {
ParseInfo pi = Request.createParseInfo(requestMsg, this.dqpWorkContext.getSession());
cacheId = new CacheID(this.dqpWorkContext, pi, requestMsg.getCommandString());
cachable = cacheId.setParameters(requestMsg.getParameterValues());
if (cachable) {
// allow cache to be transactionally aware
if (rsCache.isTransactional()) {
TransactionContext tc = request.getTransactionContext(false);
if (tc != null && tc.getTransactionType() != Scope.NONE) {
initTransactionState(tc);
resume();
}
}
CachedResults cr = rsCache.get(cacheId);
// TODO: possibly ignore max rows for caching
if (cr != null && (cr.getRowLimit() == 0 || (requestMsg.getRowLimit() != 0 && requestMsg.getRowLimit() <= cr.getRowLimit()))) {
request.initMetadata();
this.originalCommand = cr.getCommand(requestMsg.getCommandString(), request.metadata, pi);
if (!request.validateAccess(requestMsg.getCommands(), this.originalCommand, CommandType.CACHED)) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Using result set cached results", cacheId);
this.resultsBuffer = cr.getResults();
doneProducingBatches();
return;
}
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Cached result command to be modified, will not use the cached results", cacheId);
}
} else {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Parameters are not serializable - cache cannot be used for", cacheId);
}
}
} else {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Result set caching is disabled.");
}
try {
request.processRequest();
} finally {
analysisRecord = request.analysisRecord;
}
originalCommand = request.userCommand;
if (cachable && (requestMsg.useResultSetCache() || originalCommand.getCacheHint() != null) && rsCache != null && originalCommand.areResultsCachable()) {
this.cid = cacheId;
// turn on the collection of data objects used
request.processor.getContext().setDataObjects(new HashSet<Object>(4));
}
request.processor.getContext().setWorkItem(this);
processor = request.processor;
planningEnd = System.currentTimeMillis();
this.dqpCore.logMMCommand(this, Event.PLAN, null, null);
collector = new BatchCollector(processor, processor.getBufferManager(), this.request.context, isForwardOnly()) {
int maxRows = 0;
@Override
protected void flushBatchDirect(TupleBatch batch, boolean add) throws TeiidComponentException, TeiidProcessingException {
resultsBuffer = getTupleBuffer();
if (maxRows == 0) {
maxRows = OUTPUT_BUFFER_MAX_BATCHES * resultsBuffer.getBatchSize();
}
if (cid != null) {
super.flushBatchDirect(batch, add);
}
synchronized (lobStreams) {
if (cid == null && resultsBuffer.isLobs()) {
super.flushBatchDirect(batch, false);
}
if (batch.getTerminationFlag()) {
done();
}
add = sendResultsIfNeeded(batch);
if (cid != null) {
return;
}
super.flushBatchDirect(batch, add);
if (!add && !processor.hasBuffer()) {
resultsBuffer.setRowCount(batch.getEndRow());
}
if (transactionState != TransactionState.ACTIVE && (requestMsg.getRequestOptions().isContinuous() || (useCallingThread && isForwardOnly()))) {
synchronized (this) {
if (resultsReceiver == null) {
// $NON-NLS-1$
throw BlockedException.block(requestID, "Blocking to allow asynch processing");
}
}
if (add && !returnsUpdateCount) {
// $NON-NLS-1$
throw new AssertionError("Should not add batch to buffer");
}
}
if (add) {
flowControl(batch);
}
}
}
private void flowControl(TupleBatch batch) throws BlockedException {
if (processor.hasBuffer() || batch.getTerminationFlag() || transactionState == TransactionState.ACTIVE) {
return;
}
synchronized (this) {
if (!isForwardOnly() && resultsReceiver != null && begin > resultsBuffer.getRowCount()) {
// a valid request beyond the processed range
return;
}
}
if (resultsBuffer.getManagedRowCount() < maxRows) {
// continue to buffer
return;
}
int timeOut = 500;
if (!connectorInfo.isEmpty()) {
if (explicitSourceClose) {
for (DataTierTupleSource ts : getConnectorRequests()) {
if (!ts.isExplicitClose()) {
timeOut = 100;
break;
}
}
} else {
timeOut = 100;
}
}
if (dqpCore.blockOnOutputBuffer(RequestWorkItem.this)) {
if (moreWorkTask != null) {
moreWorkTask.cancel(false);
moreWorkTask = null;
}
if (getThreadState() != ThreadState.MORE_WORK) {
// we schedule the work to ensure that an idle client won't just indefinitely hold resources
moreWorkTask = scheduleWork(timeOut);
}
throw // $NON-NLS-1$
BlockedException.block(// $NON-NLS-1$
requestID, // $NON-NLS-1$
"Blocking due to full results TupleBuffer", this.getTupleBuffer(), "rows", this.getTupleBuffer().getManagedRowCount(), "batch size", // $NON-NLS-1$ //$NON-NLS-2$
this.getTupleBuffer().getBatchSize());
}
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_DQP, MessageLevel.DETAIL)) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_DQP, requestID, "Exceeding buffer limit since there are pending active plans or this is using the calling thread.");
}
}
};
if (!request.addedLimit && this.requestMsg.getRowLimit() > 0 && this.requestMsg.getRowLimit() < Integer.MAX_VALUE) {
// covers maxrows for commands that already have a limit, are prepared, or are a stored procedure
this.collector.setRowLimit(this.requestMsg.getRowLimit());
this.collector.setSaveLastRow(request.isReturingParams());
}
this.resultsBuffer = collector.getTupleBuffer();
if (this.resultsBuffer == null) {
// This is just a dummy result it will get replaced by collector source
resultsBuffer = this.processor.getBufferManager().createTupleBuffer(this.originalCommand.getProjectedSymbols(), this.request.context.getConnectionId(), TupleSourceType.FINAL);
} else if (this.requestMsg.getRequestOptions().isContinuous()) {
// TODO: this is based upon continuous being an embedded connection otherwise we have to do something like
// forcing inlining, but truncating or erroring over a given size (similar to odbc handling)
resultsBuffer.removeLobTracking();
}
initTransactionState(request.transactionContext);
if (requestMsg.isNoExec()) {
doneProducingBatches();
resultsBuffer.close();
this.cid = null;
}
this.returnsUpdateCount = request.returnsUpdateCount;
if (this.returnsUpdateCount && this.requestMsg.getRequestOptions().isContinuous()) {
// $NON-NLS-1$
throw new IllegalStateException("Continuous requests are not allowed to be updates.");
}
request = null;
}
use of org.teiid.core.TeiidComponentException in project teiid by teiid.
the class BufferFrontedFileStoreCache method get.
@Override
public CacheEntry get(PhysicalInfo info, Long oid, WeakReference<? extends Serializer<?>> ref) throws TeiidComponentException {
if (info == null) {
return null;
}
Serializer<?> serializer = ref.get();
if (serializer == null) {
return null;
}
readAttempts.incrementAndGet();
InputStream is = null;
Lock lock = null;
ExtensibleBufferedInputStream eis = null;
int memoryBlocks = 0;
try {
synchronized (info) {
// load should be locked
assert !info.pinned && info.loading;
// not necessary, but should make things safer
info.await(true, false);
if (info.inode != EMPTY_ADDRESS) {
info.pinned = true;
memoryBufferEntries.touch(info);
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_BUFFER_MGR, MessageLevel.DETAIL)) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_BUFFER_MGR, "Getting object at inode", info.inode, serializer.getId(), oid);
}
BlockManager manager = getBlockManager(serializer.getId(), oid, info.inode);
is = new BlockInputStream(manager, info.memoryBlockCount);
} else if (info.block != EMPTY_ADDRESS) {
info.pinned = true;
memoryBufferEntries.recordAccess(info);
storageReads.incrementAndGet();
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_BUFFER_MGR, MessageLevel.DETAIL)) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_BUFFER_MGR, "Getting object at block", info.block, info.sizeIndex, serializer.getId(), oid);
}
BlockStore blockStore = sizeBasedStores[info.sizeIndex];
int segment = info.block / blockStore.blocksInUse.getBitsPerSegment();
FileStore fs = blockStore.stores[segment];
long blockOffset = (info.block % blockStore.blocksInUse.getBitsPerSegment()) * blockStore.blockSize;
eis = fs.createInputStream(blockOffset, info.memoryBlockCount << LOG_BLOCK_SIZE);
lock = blockStore.locks[segment].writeLock();
memoryBlocks = info.memoryBlockCount;
} else {
return null;
}
}
if (lock != null) {
is = readIntoMemory(info, eis, lock, memoryBlocks);
}
for (int i = 0; i < HEADER_BYTES; i++) {
is.read();
}
ObjectInput dis = new ObjectInputStream(is);
CacheEntry ce = new CacheEntry(new CacheKey(oid, 1, 1), info.sizeEstimate, serializer.deserialize(dis), ref, true);
return ce;
} catch (IOException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30048, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30048, info.gid, oid));
} catch (ClassNotFoundException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30048, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30048, info.gid, oid));
} catch (InterruptedException e) {
throw new TeiidRuntimeException(QueryPlugin.Event.TEIID30049, e);
} finally {
synchronized (info) {
info.pinned = false;
info.notifyAll();
}
}
}
use of org.teiid.core.TeiidComponentException in project teiid by teiid.
the class ConnectorWorkItem method correctTypes.
private List<?> correctTypes(List row) throws TeiidException {
// TODO: add a proper intermediate schema
for (int i = 0; i < row.size(); i++) {
try {
Object value = row.get(i);
if (value == null) {
continue;
}
if (convertToRuntimeType[i]) {
Object result = convertToRuntimeType(requestMsg.getBufferManager(), value, this.schema[i], this.requestMsg.getCommandContext());
if (value == result && !DataTypeManager.DefaultDataClasses.OBJECT.equals(this.schema[i])) {
convertToRuntimeType[i] = false;
} else {
if (!explicitClose && isLob[i] && !copyLobs && !areLobsUsableAfterClose && DataTypeManager.isLOB(result.getClass()) && DataTypeManager.isLOB(DataTypeManager.convertToRuntimeType(value, false).getClass())) {
explicitClose = true;
}
row.set(i, result);
value = result;
}
}
if (convertToDesiredRuntimeType[i]) {
if (value != null) {
Object result = DataTypeManager.transformValue(value, value.getClass(), this.schema[i]);
if (isLob[i] && copyLobs) {
if (lobStore == null) {
// $NON-NLS-1$
lobStore = requestMsg.getBufferManager().createFileStore("lobs");
lobBuffer = new byte[1 << 14];
}
if (copyStreamingLobs) {
// if we are free, then we're either streaming or invalid
if (InputStreamFactory.getStorageMode((Streamable<?>) result) == StorageMode.FREE) {
try {
requestMsg.getBufferManager().persistLob((Streamable<?>) result, lobStore, lobBuffer);
explicitClose = true;
} catch (TeiidComponentException e) {
}
}
} else {
requestMsg.getBufferManager().persistLob((Streamable<?>) result, lobStore, lobBuffer);
}
} else if (value == result) {
convertToDesiredRuntimeType[i] = false;
continue;
}
row.set(i, result);
}
} else if (DataTypeManager.isValueCacheEnabled()) {
row.set(i, DataTypeManager.getCanonicalValue(value));
}
} catch (TeiidComponentException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID31176, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31176, this.requestMsg.getCommand().getProjectedSymbols().get(i), DataTypeManager.getDataTypeName(this.schema[i])));
} catch (TransformationException e) {
throw new TeiidException(QueryPlugin.Event.TEIID31176, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31176, this.requestMsg.getCommand().getProjectedSymbols().get(i), DataTypeManager.getDataTypeName(this.schema[i])));
}
}
return row;
}
use of org.teiid.core.TeiidComponentException in project teiid by teiid.
the class AuthorizationValidationVisitor method validateEntitlements.
/**
* Check that the user is entitled to access all data elements in the command.
*
* @param symbols The collection of <code>Symbol</code>s affected by these actions.
* @param actionCode The actions to validate for
* @param auditContext The {@link AuthorizationService} to use when resource auditing is done.
*/
protected void validateEntitlements(Collection<? extends LanguageObject> symbols, DataPolicy.PermissionType actionCode, Context auditContext) {
Map<String, LanguageObject> nameToSymbolMap = new LinkedHashMap<String, LanguageObject>();
for (LanguageObject symbol : symbols) {
try {
Object metadataID = null;
if (symbol instanceof ElementSymbol) {
metadataID = ((ElementSymbol) symbol).getMetadataID();
if (metadataID instanceof MultiSourceElement || metadataID instanceof TempMetadataID) {
continue;
}
} else if (symbol instanceof GroupSymbol) {
GroupSymbol group = (GroupSymbol) symbol;
metadataID = group.getMetadataID();
if (metadataID instanceof TempMetadataID) {
if (group.isProcedure()) {
Map<String, LanguageObject> procMap = new LinkedHashMap<String, LanguageObject>();
addToNameMap(((TempMetadataID) metadataID).getOriginalMetadataID(), symbol, procMap, getMetadata());
validateEntitlements(PermissionType.EXECUTE, auditContext, procMap);
} else if (group.isTempTable() && group.isImplicitTempGroupSymbol()) {
validateTemp(actionCode, group.getNonCorrelationName(), false, group, auditContext);
}
continue;
}
}
addToNameMap(metadataID, symbol, nameToSymbolMap, getMetadata());
} catch (QueryMetadataException e) {
handleException(e);
} catch (TeiidComponentException e) {
handleException(e);
}
}
validateEntitlements(actionCode, auditContext, nameToSymbolMap);
}
Aggregations