Search in sources :

Example 1 with BatchedUpdatePlanner

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);
}
Also used : Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) RelationalPlan(org.teiid.query.processor.relational.RelationalPlan) VariableContext(org.teiid.query.sql.util.VariableContext) BatchedUpdateCommand(org.teiid.query.sql.lang.BatchedUpdateCommand) LinkedList(java.util.LinkedList) QueryValidatorException(org.teiid.api.exception.query.QueryValidatorException) Command(org.teiid.query.sql.lang.Command) BatchedUpdateCommand(org.teiid.query.sql.lang.BatchedUpdateCommand) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) AccessNode(org.teiid.query.processor.relational.AccessNode) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities) BatchedUpdatePlanner(org.teiid.query.optimizer.BatchedUpdatePlanner)

Aggregations

ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 QueryValidatorException (org.teiid.api.exception.query.QueryValidatorException)1 BatchedUpdatePlanner (org.teiid.query.optimizer.BatchedUpdatePlanner)1 SourceCapabilities (org.teiid.query.optimizer.capabilities.SourceCapabilities)1 AccessNode (org.teiid.query.processor.relational.AccessNode)1 RelationalPlan (org.teiid.query.processor.relational.RelationalPlan)1 BatchedUpdateCommand (org.teiid.query.sql.lang.BatchedUpdateCommand)1 Command (org.teiid.query.sql.lang.Command)1 Constant (org.teiid.query.sql.symbol.Constant)1 VariableContext (org.teiid.query.sql.util.VariableContext)1