use of org.teiid.query.sql.lang.StoredProcedure 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.query.sql.lang.StoredProcedure in project teiid by teiid.
the class ConnectorWorkItem method setExecution.
private void setExecution(Command command, org.teiid.language.Command translatedCommand, final Execution exec) {
if (translatedCommand instanceof Call) {
// $NON-NLS-1$
this.execution = Assertion.isInstanceOf(exec, ProcedureExecution.class, "Call Executions are expected to be ProcedureExecutions");
StoredProcedure proc = (StoredProcedure) command;
if (proc.returnParameters()) {
this.procedureBatchHandler = new ProcedureBatchHandler((Call) translatedCommand, (ProcedureExecution) exec);
}
} else if (command instanceof QueryCommand) {
// $NON-NLS-1$
this.execution = Assertion.isInstanceOf(exec, ResultSetExecution.class, "QueryExpression Executions are expected to be ResultSetExecutions");
} else {
final boolean singleUpdateCount = connector.returnsSingleUpdateCount() && (translatedCommand instanceof BatchedUpdates || (translatedCommand instanceof BulkCommand && ((BulkCommand) translatedCommand).getParameterValues() != null));
// $NON-NLS-1$
Assertion.isInstanceOf(exec, UpdateExecution.class, "Update Executions are expected to be UpdateExecutions");
this.execution = new ResultSetExecution() {
private int[] results;
private int index;
@Override
public void cancel() throws TranslatorException {
exec.cancel();
}
@Override
public void close() {
exec.close();
}
@Override
public void execute() throws TranslatorException {
exec.execute();
}
@Override
public List<?> next() throws TranslatorException, DataNotAvailableException {
if (results == null) {
results = ((UpdateExecution) exec).getUpdateCounts();
}
if (singleUpdateCount) {
if (index++ < results[0]) {
return CollectionTupleSource.UPDATE_ROW;
}
return null;
}
if (index < results.length) {
return Arrays.asList(results[index++]);
}
return null;
}
};
}
}
use of org.teiid.query.sql.lang.StoredProcedure in project teiid by teiid.
the class ConnectorWorkItem method execute.
public synchronized void execute() throws TranslatorException {
if (isCancelled()) {
throw new TranslatorException(QueryPlugin.Event.TEIID30476, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30476));
}
timer.start();
try {
if (this.execution == null) {
if (this.connection == null) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.requestMsg.getAtomicRequestID(), "Processing NEW request:", this.requestMsg.getCommand() });
try {
this.connectionFactory = this.manager.getConnectionFactory();
} catch (TranslatorException e) {
if (this.connector.isSourceRequired()) {
throw e;
}
}
if (this.connectionFactory != null) {
this.connection = this.connector.getConnection(this.connectionFactory, securityContext);
}
if (this.connection == null && this.connector.isSourceRequired()) {
// $NON-NLS-1$);
throw new TranslatorException(QueryPlugin.Event.TEIID31108, QueryPlugin.Util.getString("datasource_not_found", this.manager.getConnectionName()));
}
}
Object unwrapped = null;
if (connection instanceof WrappedConnection) {
try {
unwrapped = ((WrappedConnection) connection).unwrap();
} catch (ResourceException e) {
throw new TranslatorException(QueryPlugin.Event.TEIID30477, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30477, this.manager.getConnectionName()));
}
}
// Translate the command
Command command = this.requestMsg.getCommand();
this.expectedColumns = command.getProjectedSymbols().size();
if (command instanceof StoredProcedure) {
this.expectedColumns = ((StoredProcedure) command).getResultSetColumns().size();
}
Execution exec = this.requestMsg.getCommandContext().getReusableExecution(this.manager.getId());
if (exec != null) {
((ReusableExecution) exec).reset(translatedCommand, this.securityContext, connection);
} else {
exec = connector.createExecution(translatedCommand, this.securityContext, queryMetadata, (unwrapped == null) ? this.connection : unwrapped);
}
setExecution(command, translatedCommand, exec);
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.requestMsg.getAtomicRequestID(), "Obtained execution" });
// Log the Source Command (Must be after obtaining the execution context)
manager.logSRCCommand(this.requestMsg, this.securityContext, Event.NEW, null, null);
}
// Execute query
this.execution.execute();
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_CONNECTOR, new Object[] { this.id, "Executed command" });
} catch (Throwable t) {
throw handleError(t);
} finally {
timer.stop();
}
}
use of org.teiid.query.sql.lang.StoredProcedure in project teiid by teiid.
the class ExecDynamicSqlInstruction method process.
/**
* <p>
* Processing this instruction executes the ProcessorPlan for the command on
* the CommandStatement of the update procedure language. Executing this
* plan does not effect the values of any of the variables defined as part
* of the update procedure and hence the results of the ProcessPlan
* execution need not be stored for further processing. The results are
* removed from the buffer manager immediately after execution. The program
* counter is incremented after execution of the plan.
* </p>
*
* @throws BlockedException
* if this processing the plan throws a currentVarContext
*/
public void process(ProcedurePlan procEnv) throws BlockedException, TeiidComponentException, TeiidProcessingException {
VariableContext localContext = procEnv.getCurrentVariableContext();
String query = null;
try {
Clob value = (Clob) procEnv.evaluateExpression(dynamicCommand.getSql());
if (value == null) {
throw new QueryProcessingException(QueryPlugin.Util.getString(// $NON-NLS-1$
"ExecDynamicSqlInstruction.0"));
}
if (value.length() > MAX_SQL_LENGTH) {
throw new QueryProcessingException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31204, MAX_SQL_LENGTH));
}
query = value.getSubString(1, MAX_SQL_LENGTH);
LogManager.logTrace(org.teiid.logging.LogConstants.CTX_DQP, // $NON-NLS-1$
new Object[] { "Executing dynamic sql ", query });
Command command = QueryParser.getQueryParser().parseCommand(query);
// special handling for dynamic anon blocks
if (command instanceof CreateProcedureCommand) {
if (dynamicCommand.getIntoGroup() != null || returnable) {
// and the creation of an inline view
throw new QueryProcessingException(QueryPlugin.Event.TEIID31250, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31250));
}
((CreateProcedureCommand) command).setResultSetColumns(Collections.EMPTY_LIST);
}
command.setExternalGroupContexts(dynamicCommand.getExternalGroupContexts());
command.setTemporaryMetadata(dynamicCommand.getTemporaryMetadata().clone());
updateContextWithUsingValues(procEnv, localContext);
TempMetadataStore metadataStore = command.getTemporaryMetadata();
if (dynamicCommand.getUsing() != null && !dynamicCommand.getUsing().isEmpty()) {
metadataStore.addTempGroup(Reserved.USING, new LinkedList<ElementSymbol>(dynamicCommand.getUsing().getClauseMap().keySet()));
GroupSymbol using = new GroupSymbol(Reserved.USING);
using.setMetadataID(metadataStore.getTempGroupID(Reserved.USING));
command.addExternalGroupToContext(using);
metadataStore.addTempGroup(ProcedureReservedWords.DVARS, new LinkedList<ElementSymbol>(dynamicCommand.getUsing().getClauseMap().keySet()));
using = new GroupSymbol(ProcedureReservedWords.DVARS);
using.setMetadataID(metadataStore.getTempGroupID(ProcedureReservedWords.DVARS));
command.addExternalGroupToContext(using);
}
QueryResolver.resolveCommand(command, metadata.getDesignTimeMetadata());
validateDynamicCommand(procEnv, command, value.toString());
// create a new set of variables including vars
Map<ElementSymbol, Expression> nameValueMap = createVariableValuesMap(localContext);
ValidationVisitor visitor = new ValidationVisitor();
Request.validateWithVisitor(visitor, metadata, command);
boolean insertInto = false;
boolean updateCommand = false;
if (!command.returnsResultSet() && !(command instanceof StoredProcedure)) {
if (dynamicCommand.isAsClauseSet()) {
if (dynamicCommand.getProjectedSymbols().size() != 1 || ((Expression) dynamicCommand.getProjectedSymbols().get(0)).getType() != DataTypeManager.DefaultDataClasses.INTEGER) {
throw new QueryProcessingException(QueryPlugin.Event.TEIID31157, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31157));
}
}
updateCommand = true;
} else if (dynamicCommand.getAsColumns() != null && !dynamicCommand.getAsColumns().isEmpty()) {
// $NON-NLS-1$
command = QueryRewriter.createInlineViewQuery(new GroupSymbol("X"), command, metadata, dynamicCommand.getAsColumns());
if (dynamicCommand.getIntoGroup() != null) {
Insert insert = new Insert(dynamicCommand.getIntoGroup(), dynamicCommand.getAsColumns(), Collections.emptyList());
insert.setQueryExpression((Query) command);
command = insert;
insertInto = true;
}
}
// if this is an update procedure, it could reassign variables
command = QueryRewriter.rewrite(command, metadata, procEnv.getContext(), command instanceof CreateProcedureCommand ? Collections.EMPTY_MAP : nameValueMap);
ProcessorPlan commandPlan = QueryOptimizer.optimizePlan(command, metadata, idGenerator, capFinder, AnalysisRecord.createNonRecordingRecord(), procEnv.getContext());
if (command instanceof CreateProcedureCommand && commandPlan instanceof ProcedurePlan) {
((ProcedurePlan) commandPlan).setValidateAccess(procEnv.isValidateAccess());
}
CreateCursorResultSetInstruction inst = new CreateCursorResultSetInstruction(null, commandPlan, (insertInto || updateCommand) ? Mode.UPDATE : returnable ? Mode.HOLD : Mode.NOHOLD) {
@Override
public void process(ProcedurePlan procEnv) throws BlockedException, TeiidComponentException, TeiidProcessingException {
boolean done = true;
try {
super.process(procEnv);
} catch (BlockedException e) {
done = false;
throw e;
} finally {
if (done) {
procEnv.getContext().popCall();
}
}
}
};
dynamicProgram = new Program(false);
dynamicProgram.addInstruction(inst);
if (dynamicCommand.getIntoGroup() != null) {
String groupName = dynamicCommand.getIntoGroup().getName();
if (!procEnv.getTempTableStore().hasTempTable(groupName, true)) {
// create the temp table in the parent scope
Create create = new Create();
create.setTable(new GroupSymbol(groupName));
for (ElementSymbol es : (List<ElementSymbol>) dynamicCommand.getAsColumns()) {
Column c = new Column();
c.setName(es.getShortName());
c.setRuntimeType(DataTypeManager.getDataTypeName(es.getType()));
create.getColumns().add(c);
}
procEnv.getDataManager().registerRequest(procEnv.getContext(), create, TempMetadataAdapter.TEMP_MODEL.getName(), new RegisterRequestParameter());
}
// backwards compatibility to support into with a rowcount
if (updateCommand) {
Insert insert = new Insert();
insert.setGroup(new GroupSymbol(groupName));
for (ElementSymbol es : (List<ElementSymbol>) dynamicCommand.getAsColumns()) {
ElementSymbol col = new ElementSymbol(es.getShortName(), insert.getGroup());
col.setType(es.getType());
insert.addVariable(col);
}
insert.addValue(new Constant(procEnv.getCurrentVariableContext().getValue(ProcedurePlan.ROWCOUNT)));
QueryResolver.resolveCommand(insert, metadata.getDesignTimeMetadata());
TupleSource ts = procEnv.getDataManager().registerRequest(procEnv.getContext(), insert, TempMetadataAdapter.TEMP_MODEL.getName(), new RegisterRequestParameter());
ts.nextTuple();
ts.closeSource();
}
}
// Add group to recursion stack
if (parentProcCommand.getUpdateType() != Command.TYPE_UNKNOWN) {
// $NON-NLS-1$
procEnv.getContext().pushCall(Command.getCommandToken(parentProcCommand.getUpdateType()) + " " + parentProcCommand.getVirtualGroup());
} else {
if (parentProcCommand.getVirtualGroup() != null) {
procEnv.getContext().pushCall(parentProcCommand.getVirtualGroup().toString());
}
}
procEnv.push(dynamicProgram);
} catch (SQLException e) {
Object[] params = { dynamicCommand, dynamicCommand.getSql(), e.getMessage() };
throw new QueryProcessingException(QueryPlugin.Event.TEIID30168, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30168, params));
} catch (TeiidProcessingException e) {
Object[] params = { dynamicCommand, query == null ? dynamicCommand.getSql() : query, e.getMessage() };
throw new QueryProcessingException(QueryPlugin.Event.TEIID30168, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30168, params));
}
}
use of org.teiid.query.sql.lang.StoredProcedure in project teiid by teiid.
the class ProcedureContainerResolver method expandCommand.
/**
* Expand a command by finding and attaching all subcommands to the command. If
* some initial resolution must be done for this to be accomplished, that is ok,
* but it should be kept to a minimum.
* @param command The command to expand
* @param useMetadataCommands True if resolver should use metadata commands to completely resolve
* @param metadata Metadata access
* @param analysis The analysis record that will be filled in if doing annotation.
*
* @throws QueryMetadataException If there is a metadata problem
* @throws QueryResolverException If the query cannot be resolved
* @throws TeiidComponentException If there is an internal error
*/
public Command expandCommand(ProcedureContainer procCommand, QueryMetadataInterface metadata, AnalysisRecord analysis) throws QueryMetadataException, QueryResolverException, TeiidComponentException {
// Resolve group so we can tell whether it is an update procedure
GroupSymbol group = procCommand.getGroup();
Command subCommand = null;
String plan = getPlan(metadata, procCommand);
if (plan == null) {
return null;
}
QueryParser parser = QueryParser.getQueryParser();
try {
subCommand = parser.parseProcedure(plan, !(procCommand instanceof StoredProcedure));
} catch (QueryParserException e) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30060, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30060, group, procCommand.getClass().getSimpleName()));
}
return subCommand;
}
Aggregations