PlanNodeFragment * PlanNodeFragment::fromJSONObject(PlannerDomValue obj) { PlanNodeFragment *retval = new PlanNodeFragment(); auto_ptr<PlanNodeFragment> pnf(retval); // read and construct plannodes from json object if (obj.hasNonNullKey("PLAN_NODES_LISTS")) { PlannerDomValue planNodesListArray = obj.valueForKey("PLAN_NODES_LISTS"); if (!obj.hasNonNullKey("EXECUTE_LISTS")) { throwFatalException("Failed to construct plan fragment. Missing EXECUTE_LISTS key"); } PlannerDomValue executeListArray = obj.valueForKey("EXECUTE_LISTS"); if (planNodesListArray.arrayLen() != executeListArray.arrayLen()) { throwFatalException("Failed to construct plan fragment. EXECUTE_LISTS and PLAN_NODES_LISTS do not match"); } int stmtCnt = planNodesListArray.arrayLen(); for (int i = 0; i < stmtCnt; i++) { int stmtId = planNodesListArray.valueAtIndex(i).valueForKey("STATEMENT_ID").asInt(); PlannerDomValue planNodesList = planNodesListArray.valueAtIndex(i).valueForKey("PLAN_NODES"); PlannerDomValue executeList = executeListArray.valueAtIndex(i).valueForKey("EXECUTE_LIST"); retval->nodeListFromJSONObject(planNodesList, executeList, stmtId); } } else { retval->nodeListFromJSONObject(obj.valueForKey("PLAN_NODES"), obj.valueForKey("EXECUTE_LIST"), 0); } pnf.release(); return retval; }
// ------------------------------------------------- // Initialization Functions // ------------------------------------------------- bool VoltDBEngine::initPlanFragment(const int64_t fragId, const string planNodeTree) { // Deserialize the PlanFragment and stick in our local map map<int64_t, boost::shared_ptr<ExecutorVector> >::const_iterator iter = m_executorMap.find(fragId); if (iter != m_executorMap.end()) { VOLT_ERROR("Duplicate PlanNodeList entry for PlanFragment '%jd' during" " initialization", (intmax_t)fragId); return false; } // catalog method plannodetree returns PlanNodeList.java PlanNodeFragment *pnf = PlanNodeFragment::createFromCatalog(planNodeTree); VOLT_TRACE("\n%s\n", pnf->debug().c_str()); assert(pnf->getRootNode()); if (!pnf->getRootNode()) { VOLT_ERROR("Deserialized PlanNodeFragment for PlanFragment '%jd' " "does not have a root PlanNode", (intmax_t)fragId); return false; } // ENG-1333 HACK. If the plan node fragment has a delete node, // then turn off the governors int64_t frag_temptable_log_limit = (m_tempTableMemoryLimit * 3) / 4; int64_t frag_temptable_limit = m_tempTableMemoryLimit; if (pnf->hasDelete()) { frag_temptable_log_limit = DEFAULT_TEMP_TABLE_MEMORY; frag_temptable_limit = -1; } boost::shared_ptr<ExecutorVector> ev = boost::shared_ptr<ExecutorVector> (new ExecutorVector(frag_temptable_log_limit, frag_temptable_limit, pnf)); // Initialize each node! for (int ctr = 0, cnt = (int)pnf->getExecuteList().size(); ctr < cnt; ctr++) { if (!initPlanNode(fragId, pnf->getExecuteList()[ctr], &(ev->limits))) { VOLT_ERROR("Failed to initialize PlanNode '%s' at position '%d'" " for PlanFragment '%jd'", pnf->getExecuteList()[ctr]->debug().c_str(), ctr, (intmax_t)fragId); return false; } } // Initialize the vector of executors for this planfragment, used at runtime. for (int ctr = 0, cnt = (int)pnf->getExecuteList().size(); ctr < cnt; ctr++) { ev->list.push_back(pnf->getExecuteList()[ctr]->getExecutor()); } m_executorMap[fragId] = ev; return true; }
PlanNodeFragment * PlanNodeFragment::fromJSONObject(json_spirit::Object &obj) { json_spirit::Value planNodesValue = json_spirit::find_value( obj, "PLAN_NODES"); if (planNodesValue == json_spirit::Value::null) { throwFatalException("Failure attempting to load plan a plan node fragment from a " "json_spirit::Object. There was no value \"PLAN_NODES\""); } PlanNodeFragment * pnf = new PlanNodeFragment(); // read and construct plannodes from json object json_spirit::Array planNodesArray = planNodesValue.get_array(); for (int ii = 0; ii < planNodesArray.size(); ii++) { AbstractPlanNode *node = NULL; try { node = AbstractPlanNode::fromJSONObject(planNodesArray[ii].get_obj()); } catch (SerializableEEException &ex) { delete pnf; throw; } pnf->m_planNodes.push_back(node); pnf->m_idToNodeMap[node->getPlanNodeId()] = node; } // walk the plannodes and complete each plannode's id-to-node maps for (std::vector< AbstractPlanNode* >::const_iterator node = pnf->m_planNodes.begin(); node != pnf->m_planNodes.end(); ++node) { const std::vector<CatalogId> childIds = (*node)->getChildIds(); std::vector<AbstractPlanNode*> &children = (*node)->getChildren(); for (int zz = 0; zz < childIds.size(); zz++) { children.push_back(pnf->m_idToNodeMap[childIds[zz]]); } const std::vector<CatalogId> parentIds = (*node)->getParentIds(); std::vector<AbstractPlanNode*> &parents = (*node)->getParents(); for (int zz = 0; zz < parentIds.size(); zz++) { parents.push_back(pnf->m_idToNodeMap[parentIds[zz]]); } } try { pnf->loadFromJSONObject(obj); } catch (SerializableEEException &eeEx) { delete pnf; throw; } return pnf; }
boost::shared_ptr<ExecutorVector> ExecutorVector::fromJsonPlan(VoltDBEngine* engine, const std::string& jsonPlan, int64_t fragId) { PlanNodeFragment *pnf = NULL; try { pnf = PlanNodeFragment::createFromCatalog(jsonPlan); } catch (SerializableEEException &seee) { throw; } catch (...) { char msg[1024 * 100]; snprintf(msg, 1024 * 100, "Unable to initialize PlanNodeFragment for PlanFragment '%jd' with plan:\n%s", (intmax_t)fragId, jsonPlan.c_str()); VOLT_ERROR("%s", msg); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, msg); } VOLT_TRACE("\n%s\n", pnf->debug().c_str()); assert(pnf->getRootNode()); if (!pnf->getRootNode()) { char msg[1024]; snprintf(msg, 1024, "Deserialized PlanNodeFragment for PlanFragment '%jd' does not have a root PlanNode", (intmax_t)fragId); VOLT_ERROR("%s", msg); throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, msg); } int64_t tempTableLogLimit = engine->tempTableLogLimit(); int64_t tempTableMemoryLimit = engine->tempTableMemoryLimit(); // ENG-1333 HACK. If the plan node fragment has a delete node, // then turn off the governors if (pnf->hasDelete()) { tempTableLogLimit = DEFAULT_TEMP_TABLE_MEMORY; tempTableMemoryLimit = -1; } // Note: the executor vector takes ownership of the plan node // fragment here. boost::shared_ptr<ExecutorVector> ev(new ExecutorVector(fragId, tempTableLogLimit, tempTableMemoryLimit, pnf)); ev->init(engine); return ev; }