use of org.teiid.query.optimizer.BatchedUpdatePlanner in project teiid by teiid.
the class PreparedStatementRequest method handlePreparedBatchUpdate.
/**
* There are two cases
* if
* The source supports preparedBatchUpdate -> just let the command and values pass to the source
* else
* create a batchedupdatecommand that represents the batch operation
* @param command
* @throws QueryMetadataException
* @throws TeiidComponentException
* @throws QueryResolverException
* @throws QueryPlannerException
* @throws QueryValidatorException
*/
private void handlePreparedBatchUpdate() throws QueryMetadataException, TeiidComponentException, QueryResolverException, QueryPlannerException, QueryValidatorException {
List<List<?>> paramValues = (List<List<?>>) requestMsg.getParameterValues();
if (paramValues.isEmpty()) {
throw new QueryValidatorException(QueryPlugin.Event.TEIID30555, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30555));
}
boolean supportPreparedBatchUpdate = false;
Command command = null;
if (this.processPlan instanceof RelationalPlan) {
RelationalPlan rPlan = (RelationalPlan) this.processPlan;
if (rPlan.getRootNode() instanceof AccessNode) {
AccessNode aNode = (AccessNode) rPlan.getRootNode();
String modelName = aNode.getModelName();
command = aNode.getCommand();
SourceCapabilities caps = capabilitiesFinder.findCapabilities(modelName);
supportPreparedBatchUpdate = caps.supportsCapability(SourceCapabilities.Capability.BULK_UPDATE);
if (supportPreparedBatchUpdate && // only allow the plan if the multi-valued references result in expressions that can be pushed
!CriteriaCapabilityValidatorVisitor.canPushLanguageObject(command, metadata.getModelID(modelName), metadata, capabilitiesFinder, analysisRecord, false, false, true)) {
supportPreparedBatchUpdate = false;
}
}
}
List<Command> commands = new LinkedList<Command>();
List<VariableContext> contexts = new LinkedList<VariableContext>();
List<List<Object>> multiValues = new ArrayList<List<Object>>(this.prepPlan.getReferences().size());
for (List<?> values : paramValues) {
PreparedStatementRequest.resolveParameterValues(this.prepPlan.getReferences(), values, this.context, this.metadata);
contexts.add(this.context.getVariableContext());
if (supportPreparedBatchUpdate) {
if (multiValues.isEmpty()) {
for (int i = 0; i < values.size(); i++) {
multiValues.add(new ArrayList<Object>(paramValues.size()));
}
}
for (int i = 0; i < values.size(); i++) {
List<Object> multiValue = multiValues.get(i);
Object value = this.context.getVariableContext().getGlobalValue(this.prepPlan.getReferences().get(i).getContextSymbol());
multiValue.add(value);
}
} else {
// just accumulate copies of the command/plan - clones are not necessary
if (command == null) {
command = this.prepPlan.getCommand();
}
command.setProcessorPlan(this.processPlan);
commands.add(command);
}
}
if (paramValues.size() > 1) {
this.context.setVariableContext(new VariableContext());
}
if (paramValues.size() == 1) {
// just use the existing plan, and global reference evaluation
return;
}
if (supportPreparedBatchUpdate) {
for (int i = 0; i < this.prepPlan.getReferences().size(); i++) {
Constant c = new Constant(null, this.prepPlan.getReferences().get(i).getType());
c.setMultiValued(multiValues.get(i));
this.context.getVariableContext().setGlobalValue(this.prepPlan.getReferences().get(i).getContextSymbol(), c);
}
return;
}
BatchedUpdateCommand buc = new BatchedUpdateCommand(commands);
buc.setVariableContexts(contexts);
BatchedUpdatePlanner planner = new BatchedUpdatePlanner();
this.processPlan = planner.optimize(buc, idGenerator, metadata, capabilitiesFinder, analysisRecord, context);
}
Aggregations