// want to prefetch and extract the ProcParameters
// to populate an array of ParameterSets to use as the batchArgs
int hashcode = VoltProcedure.getBatchHashCode(prefetchStmts, prefetchStmts.length);
// Check if we've used this planner in the past. If not, then create it.
BatchPlanner planner = this.planners.get().get(hashcode);
if (planner == null) {
planner = this.addPlanner(ts.getProcedure(), prefetchable, prefetchStmts);
}
assert(planner != null) : "Missing BatchPlanner for " + ts.getProcedure();
final ParameterSet prefetchParams[] = new ParameterSet[planner.getBatchSize()];
final int prefetchCounters[] = new int[planner.getBatchSize()];
final ByteString prefetchParamsSerialized[] = new ByteString[prefetchParams.length];
final int basePartition = ts.getBasePartition();
// Makes a list of ByteStrings containing the ParameterSets that we need
// to send over to the remote sites so that they can execute our
// prefetchable queries
Object proc_params[] = procParams.toArray();
for (int i = 0; i < prefetchParams.length; i++) {
CountedStatement counted_stmt = prefetchable.get(i);
if (debug.val)
LOG.debug(String.format("%s - Building ParameterSet for prefetchable query %s",
ts, counted_stmt));
Object stmt_params[] = new Object[counted_stmt.statement.getParameters().size()];
// Generates a new object array using a mapping from the
// ProcParameter to the StmtParameter. This relies on a
// ParameterMapping already being installed in the catalog
for (StmtParameter catalog_param : counted_stmt.statement.getParameters().values()) {
Collection<ParameterMapping> pmSets = this.catalogContext.paramMappings.get(
counted_stmt.statement,
counted_stmt.counter,
catalog_param);
assert(pmSets != null) :
String.format("Unexpected null %s %s set for %s",
counted_stmt, ParameterMapping.class.getSimpleName(), catalog_param);
ParameterMapping pm = CollectionUtil.first(pmSets);
assert(pm != null) :
String.format("Unexpected null %s for %s [%s]",
ParameterMapping.class.getSimpleName(),
catalog_param.fullName(), counted_stmt);
assert(pm.statement_index == counted_stmt.counter) :
String.format("Mismatch StmtCounter for %s - Expected[%d] != Actual[%d]\n%s",
counted_stmt, counted_stmt.counter, pm.statement_index, pm);
if (pm.procedure_parameter.getIsarray()) {
try {
stmt_params[catalog_param.getIndex()] = ParametersUtil.getValue(procParams, pm);
} catch (Throwable ex) {
String msg = String.format("Unable to get %s value for %s in %s\n" +
"ProcParams: %s\nParameterMapping: %s",
catalog_param.fullName(), ts, counted_stmt,
procParams, pm);
LOG.error(msg, ex);
throw new ServerFaultException(msg, ex, ts.getTransactionId());
}
}
else {
ProcParameter catalog_proc_param = pm.procedure_parameter;
assert(catalog_proc_param != null) :
"Missing mapping from " + catalog_param.fullName() + " to ProcParameter";
stmt_params[catalog_param.getIndex()] = proc_params[catalog_proc_param.getIndex()];
}
} // FOR (StmtParameter)
prefetchParams[i] = new ParameterSet(stmt_params);
prefetchCounters[i] = counted_stmt.counter;
if (debug.val)
LOG.debug(String.format("%s - [Prefetch %02d] %s -> %s",
ts, i, counted_stmt, prefetchParams[i]));
// Serialize this ParameterSet for the TransactionInitRequests
try {
fs.clear();
prefetchParams[i].writeExternal(fs);
prefetchParamsSerialized[i] = ByteString.copyFrom(fs.getBBContainer().b);
} catch (Exception ex) {
throw new RuntimeException("Failed to serialize ParameterSet " + i + " for " + ts, ex);
}
} // FOR (Statement)
// Generate the WorkFragments that we will need to send in our TransactionInitRequest
BatchPlan plan = planner.plan(ts.getTransactionId(),
basePartition,
ts.getPredictTouchedPartitions(),
ts.getTouchedPartitions(),
prefetchParams);
List<WorkFragment.Builder> fragmentBuilders = new ArrayList<WorkFragment.Builder>();