Procedure catalog_proc = catalogStmt.getParent();
boolean isMapReduce = catalog_proc.getMapreduce();
CompiledPlan plan = null;
CompiledPlan last_plan = null;
PlanNodeList node_list = null;
QueryPlanner planner = new QueryPlanner(catalog.getClusters().get("cluster"), db, hsql, estimates, true, false);
Throwable first_exception = null;
for (boolean _singleSited : new boolean[]{ true, false }) {
if (_singleSited == false && isMapReduce) continue;
QueryType stmt_type = QueryType.get(catalogStmt.getQuerytype());
String msg = "Creating " + stmt_type.name() + " query plan for " + catalogStmt.fullName() + ": singleSited=" + _singleSited;
if (trace.val) LOG.trace(msg);
compiler.addInfo(msg);
catalogStmt.setSinglepartition(_singleSited);
String name = catalogStmt.getParent().getName() + "-" + catalogStmt.getName();
TrivialCostModel costModel = new TrivialCostModel();
try {
plan = planner.compilePlan(costModel, catalogStmt.getSqltext(),
catalogStmt.getName(), catalogStmt.getParent().getName(),
catalogStmt.getSinglepartition(), null);
} catch (Throwable e) {
LOG.error("Failed to plan for stmt: " + catalogStmt.fullName(), e);
if (first_exception == null) {
if (debug.val) LOG.warn("Ignoring first error for " + catalogStmt.getName() + " :: " + e.getMessage());
first_exception = e;
continue;
}
e.printStackTrace();
throw compiler.new VoltCompilerException("Failed to plan for stmt: " + catalogStmt.fullName());
}
if (plan == null) {
msg = "Failed to plan for stmt: " + catalogStmt.fullName();
String plannerMsg = planner.getErrorMessage();
if (plannerMsg == null) plannerMsg = "PlannerMessage was empty!";
// HACK: Ignore if they were trying to do a single-sited INSERT/UPDATE/DELETE
// on a replicated table
if (plannerMsg.contains("replicated table") && _singleSited) {
if (debug.val)
LOG.warn(String.format("Ignoring error for %s: %s", catalogStmt.fullName(), plannerMsg));
continue;
// HACK: If we get an unknown error message on an multi-sited INSERT/UPDATE/DELETE, assume
// that it's because we are trying to insert on a non-replicated table
} else if (!_singleSited && stmt_type == QueryType.INSERT && plannerMsg.contains("Error unknown")) {
if (debug.val)
LOG.warn(String.format("Ignoring multi-sited %s %s on non-replicated table: %s",
stmt_type.name(), catalogStmt.fullName(), plannerMsg));
continue;
} else if (planner.getError() != null) {
if (debug.val) LOG.error(msg);
throw compiler.new VoltCompilerException(msg, planner.getError());
// Otherwise, report the error
} else {
if (plannerMsg != null)
msg += " with error: \"" + plannerMsg + "\"";
if (debug.val) LOG.error(msg);
throw compiler.new VoltCompilerException(msg);
}
}
if (trace.val)
LOG.trace(String.format("%s Analyzing %s query plan",
catalogStmt.fullName(), (_singleSited == false ? "DTXN" : "SP")));
// serialize full where clause to the catalog
// for the benefit of the designer
if (plan.fullWhereClause != null) {
String json = "ERROR";
try {
// serialize to pretty printed json
String jsonCompact = plan.fullWhereClause.toJSONString();
// pretty printing seems to cause issues
//JSONObject jobj = new JSONObject(jsonCompact);
//json = jobj.toString(4);
json = jsonCompact;
} catch (Exception e) {
// hopefully someone will notice
e.printStackTrace();
}
String hexString = Encoder.hexEncode(json);
catalogStmt.setExptree(hexString);
}
// serialize full plan to the catalog
// for the benefit of the designer
if (plan.fullWinnerPlan != null) {
String json = plan.fullplan_json;
String hexString = Encoder.hexEncode(json);
if (_singleSited) {
catalogStmt.setFullplan(hexString);
} else {
catalogStmt.setMs_fullplan(hexString);
}
}
//Store the list of parameters types and indexes in the plan node list.
/*List<Pair<Integer, VoltType>> parameters = node_list.getParameters();
for (ParameterInfo param : plan.parameters) {
Pair<Integer, VoltType> parameter = new Pair<Integer, VoltType>(param.index, param.type);
parameters.add(parameter);
}*/
int i = 0;
Collections.sort(plan.fragments);
if (trace.val)
LOG.trace(catalogStmt.fullName() + " Plan Fragments: " + plan.fragments);
for (CompiledPlan.Fragment fragment : plan.fragments) {
node_list = new PlanNodeList(fragment.planGraph);
boolean readonly = fragmentReadOnly(fragment.planGraph);
boolean fastAggregate = false; // FIXME
boolean fastCombine = false; // FIXME
// Now update our catalog information
int id = getNextFragmentId(db, readonly, fastAggregate, fastCombine);
String planFragmentName = Integer.toString(id);
PlanFragment planFragment = null;
if (_singleSited) {
planFragment = catalogStmt.getFragments().add(planFragmentName);
catalogStmt.setHas_singlesited(true);
if (trace.val)
LOG.trace(String.format("%s SP PLAN FRAGMENT: %s", catalogStmt.fullName(), planFragment));
} else {
planFragment = catalogStmt.getMs_fragments().add(planFragmentName);
catalogStmt.setHas_multisited(true);
if (trace.val)
LOG.trace(String.format("%s DTXN PLAN FRAGMENT: %s", catalogStmt.fullName(), planFragment));
}
// mark a fragment as non-transactional if it never touches a persistent table
planFragment.setNontransactional(!fragmentReferencesPersistentTable(fragment.planGraph));
planFragment.setReadonly(readonly);
planFragment.setHasdependencies(fragment.hasDependencies);
planFragment.setMultipartition(fragment.multiPartition);
planFragment.setId(id);
String json = null;
try {
JSONObject jobj = new JSONObject(node_list.toJSONString());
json = jobj.toString(4);
} catch (JSONException e2) {
throw new RuntimeException(e2);
}