string WebPage::evaluateRegexOnXPath_first(string exp, string xpath, int pos) { evaluateXPath(xpath); if (xpathObj) { string flattened; for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlChar *strRep = xmlXPathCastNodeToString(xpathObj->nodesetval->nodeTab[i]); string nodeStr((char*)strRep); if (!nodeStr.empty()) flattened += nodeStr + string("\n"); xmlFree(strRep); } regex rankREGEX(exp); smatch match; regex_search(flattened, match, rankREGEX); if (pos < match.size()) return match[pos].str(); else return ""; } else return ""; }
vector<string> WebPage::evaluateRegexOnXPath(string exp, string xpath) { vector<string> rVal; evaluateXPath(xpath); if (xpathObj) { string flattened; for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlChar *strRep = xmlXPathCastNodeToString(xpathObj->nodesetval->nodeTab[i]); string nodeStr((char*)strRep); if (!nodeStr.empty()) flattened += nodeStr + string("\n"); xmlFree(strRep); } regex rankREGEX(exp); sregex_iterator it(flattened.begin(), flattened.end(), rankREGEX); sregex_iterator it_end; while (it != it_end) { rVal.push_back((*it).str()); it++; } return rVal; } else return rVal; }
NS_IMETHODIMP nsLocalFile::GetRelativeDescriptor(nsIFile *fromFile, nsACString& _retval) { NS_ENSURE_ARG_POINTER(fromFile); const int32_t kMaxNodesInPath = 32; // // _retval will be UTF-8 encoded // nsresult rv; _retval.Truncate(0); nsAutoString thisPath, fromPath; PRUnichar *thisNodes[kMaxNodesInPath], *fromNodes[kMaxNodesInPath]; int32_t thisNodeCnt, fromNodeCnt, nodeIndex; rv = GetPath(thisPath); if (NS_FAILED(rv)) return rv; rv = fromFile->GetPath(fromPath); if (NS_FAILED(rv)) return rv; // get raw pointer to mutable string buffer PRUnichar *thisPathPtr; thisPath.BeginWriting(thisPathPtr); PRUnichar *fromPathPtr; fromPath.BeginWriting(fromPathPtr); thisNodeCnt = SplitPath(thisPathPtr, thisNodes, kMaxNodesInPath); fromNodeCnt = SplitPath(fromPathPtr, fromNodes, kMaxNodesInPath); if (thisNodeCnt < 0 || fromNodeCnt < 0) return NS_ERROR_FAILURE; for (nodeIndex = 0; nodeIndex < thisNodeCnt && nodeIndex < fromNodeCnt; ++nodeIndex) { #ifdef XP_WIN if (_wcsicmp(thisNodes[nodeIndex], fromNodes[nodeIndex])) break; #else if (nsCRT::strcmp(thisNodes[nodeIndex], fromNodes[nodeIndex])) break; #endif } int32_t branchIndex = nodeIndex; for (nodeIndex = branchIndex; nodeIndex < fromNodeCnt; nodeIndex++) _retval.AppendLiteral("../"); for (nodeIndex = branchIndex; nodeIndex < thisNodeCnt; nodeIndex++) { NS_ConvertUTF16toUTF8 nodeStr(thisNodes[nodeIndex]); _retval.Append(nodeStr); if (nodeIndex + 1 < thisNodeCnt) _retval.Append('/'); } return NS_OK; }
std::string Serialize(Node* node) { if (node == NULL) { return "#!"; } std::string nodeStr(node->ToString()); nodeStr.append("!"); nodeStr += Serialize(node->left); nodeStr += Serialize(node->right); return nodeStr; }
PlanStage* buildStages(OperationContext* txn, Collection* collection, const QuerySolution& qsol, const QuerySolutionNode* root, WorkingSet* ws) { if (STAGE_COLLSCAN == root->getType()) { const CollectionScanNode* csn = static_cast<const CollectionScanNode*>(root); CollectionScanParams params; params.collection = collection; params.tailable = csn->tailable; params.direction = (csn->direction == 1) ? CollectionScanParams::FORWARD : CollectionScanParams::BACKWARD; params.maxScan = csn->maxScan; return new CollectionScan(txn, params, ws, csn->filter.get()); } else if (STAGE_IXSCAN == root->getType()) { const IndexScanNode* ixn = static_cast<const IndexScanNode*>(root); if (NULL == collection) { warning() << "Can't ixscan null namespace"; return NULL; } IndexScanParams params; params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern( txn, ixn->indexKeyPattern ); if ( params.descriptor == NULL ) { warning() << "Can't find index " << ixn->indexKeyPattern.toString() << "in namespace " << collection->ns() << endl; return NULL; } params.bounds = ixn->bounds; params.direction = ixn->direction; params.maxScan = ixn->maxScan; params.addKeyMetadata = ixn->addKeyMetadata; return new IndexScan(txn, params, ws, ixn->filter.get()); } else if (STAGE_FETCH == root->getType()) { const FetchNode* fn = static_cast<const FetchNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } return new FetchStage(txn, ws, childStage, fn->filter.get(), collection); } else if (STAGE_SORT == root->getType()) { const SortNode* sn = static_cast<const SortNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } SortStageParams params; params.collection = collection; params.pattern = sn->pattern; params.query = sn->query; params.limit = sn->limit; return new SortStage(txn, params, ws, childStage); } else if (STAGE_PROJECTION == root->getType()) { const ProjectionNode* pn = static_cast<const ProjectionNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, pn->children[0], ws); if (NULL == childStage) { return NULL; } ProjectionStageParams params(WhereCallbackReal(txn, collection->ns().db())); params.projObj = pn->projection; // Stuff the right data into the params depending on what proj impl we use. if (ProjectionNode::DEFAULT == pn->projType) { params.fullExpression = pn->fullExpression; params.projImpl = ProjectionStageParams::NO_FAST_PATH; } else if (ProjectionNode::COVERED_ONE_INDEX == pn->projType) { params.projImpl = ProjectionStageParams::COVERED_ONE_INDEX; params.coveredKeyObj = pn->coveredKeyObj; invariant(!pn->coveredKeyObj.isEmpty()); } else { invariant(ProjectionNode::SIMPLE_DOC == pn->projType); params.projImpl = ProjectionStageParams::SIMPLE_DOC; } return new ProjectionStage(params, ws, childStage); } else if (STAGE_LIMIT == root->getType()) { const LimitNode* ln = static_cast<const LimitNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, ln->children[0], ws); if (NULL == childStage) { return NULL; } return new LimitStage(ln->limit, ws, childStage); } else if (STAGE_SKIP == root->getType()) { const SkipNode* sn = static_cast<const SkipNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } return new SkipStage(sn->skip, ws, childStage); } else if (STAGE_AND_HASH == root->getType()) { const AndHashNode* ahn = static_cast<const AndHashNode*>(root); auto_ptr<AndHashStage> ret(new AndHashStage(txn, ws, ahn->filter.get(), collection)); for (size_t i = 0; i < ahn->children.size(); ++i) { PlanStage* childStage = buildStages(txn, collection, qsol, ahn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_OR == root->getType()) { const OrNode * orn = static_cast<const OrNode*>(root); auto_ptr<OrStage> ret(new OrStage(ws, orn->dedup, orn->filter.get())); for (size_t i = 0; i < orn->children.size(); ++i) { PlanStage* childStage = buildStages(txn, collection, qsol, orn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_AND_SORTED == root->getType()) { const AndSortedNode* asn = static_cast<const AndSortedNode*>(root); auto_ptr<AndSortedStage> ret(new AndSortedStage(txn, ws, asn->filter.get(), collection)); for (size_t i = 0; i < asn->children.size(); ++i) { PlanStage* childStage = buildStages(txn, collection, qsol, asn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_SORT_MERGE == root->getType()) { const MergeSortNode* msn = static_cast<const MergeSortNode*>(root); MergeSortStageParams params; params.dedup = msn->dedup; params.pattern = msn->sort; auto_ptr<MergeSortStage> ret(new MergeSortStage(txn, params, ws, collection)); for (size_t i = 0; i < msn->children.size(); ++i) { PlanStage* childStage = buildStages(txn, collection, qsol, msn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_GEO_NEAR_2D == root->getType()) { const GeoNear2DNode* node = static_cast<const GeoNear2DNode*>(root); GeoNearParams params; params.nearQuery = node->nq; params.baseBounds = node->baseBounds; params.filter = node->filter.get(); params.addPointMeta = node->addPointMeta; params.addDistMeta = node->addDistMeta; IndexDescriptor* twoDIndex = collection->getIndexCatalog()->findIndexByKeyPattern(txn, node->indexKeyPattern); if (twoDIndex == NULL) { warning() << "Can't find 2D index " << node->indexKeyPattern.toString() << "in namespace " << collection->ns() << endl; return NULL; } GeoNear2DStage* nearStage = new GeoNear2DStage(params, txn, ws, collection, twoDIndex); return nearStage; } else if (STAGE_GEO_NEAR_2DSPHERE == root->getType()) { const GeoNear2DSphereNode* node = static_cast<const GeoNear2DSphereNode*>(root); GeoNearParams params; params.nearQuery = node->nq; params.baseBounds = node->baseBounds; params.filter = node->filter.get(); params.addPointMeta = node->addPointMeta; params.addDistMeta = node->addDistMeta; IndexDescriptor* s2Index = collection->getIndexCatalog()->findIndexByKeyPattern(txn, node->indexKeyPattern); if (s2Index == NULL) { warning() << "Can't find 2DSphere index " << node->indexKeyPattern.toString() << "in namespace " << collection->ns() << endl; return NULL; } return new GeoNear2DSphereStage(params, txn, ws, collection, s2Index); } else if (STAGE_TEXT == root->getType()) { const TextNode* node = static_cast<const TextNode*>(root); if (NULL == collection) { warning() << "Null collection for text"; return NULL; } vector<IndexDescriptor*> idxMatches; collection->getIndexCatalog()->findIndexByType(txn, "text", idxMatches); if (1 != idxMatches.size()) { warning() << "No text index, or more than one text index"; return NULL; } IndexDescriptor* index = idxMatches[0]; const FTSAccessMethod* fam = static_cast<FTSAccessMethod*>( collection->getIndexCatalog()->getIndex( index ) ); TextStageParams params(fam->getSpec()); //params.collection = collection; params.index = index; params.spec = fam->getSpec(); params.indexPrefix = node->indexPrefix; const std::string& language = ("" == node->language ? fam->getSpec().defaultLanguage().str() : node->language); Status parseStatus = params.query.parse(node->query, language, fam->getSpec().getTextIndexVersion()); if (!parseStatus.isOK()) { warning() << "Can't parse text search query"; return NULL; } return new TextStage(txn, params, ws, node->filter.get()); } else if (STAGE_SHARDING_FILTER == root->getType()) { const ShardingFilterNode* fn = static_cast<const ShardingFilterNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } return new ShardFilterStage(shardingState.getCollectionMetadata(collection->ns()), ws, childStage); } else if (STAGE_KEEP_MUTATIONS == root->getType()) { const KeepMutationsNode* km = static_cast<const KeepMutationsNode*>(root); PlanStage* childStage = buildStages(txn, collection, qsol, km->children[0], ws); if (NULL == childStage) { return NULL; } return new KeepMutationsStage(km->filter.get(), ws, childStage); } else if (STAGE_DISTINCT == root->getType()) { const DistinctNode* dn = static_cast<const DistinctNode*>(root); if (NULL == collection) { warning() << "Can't distinct-scan null namespace"; return NULL; } DistinctParams params; params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern(txn, dn->indexKeyPattern); params.direction = dn->direction; params.bounds = dn->bounds; params.fieldNo = dn->fieldNo; return new DistinctScan(txn, params, ws); } else if (STAGE_COUNT_SCAN == root->getType()) { const CountNode* cn = static_cast<const CountNode*>(root); if (NULL == collection) { warning() << "Can't fast-count null namespace (collection null)"; return NULL; } CountScanParams params; params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern(txn, cn->indexKeyPattern); params.startKey = cn->startKey; params.startKeyInclusive = cn->startKeyInclusive; params.endKey = cn->endKey; params.endKeyInclusive = cn->endKeyInclusive; return new CountScan(txn, params, ws); } else { mongoutils::str::stream ss; root->appendToString(&ss, 0); string nodeStr(ss); warning() << "Can't build exec tree for node " << nodeStr << endl; return NULL; } }
NS_IMETHODIMP nsLocalFile::GetRelativeDescriptor(nsIFile* aFromFile, nsACString& aResult) { if (NS_WARN_IF(!aFromFile)) { return NS_ERROR_INVALID_ARG; } const int32_t kMaxNodesInPath = 32; // // aResult will be UTF-8 encoded // nsresult rv; aResult.Truncate(0); nsAutoString thisPath, fromPath; char16_t* thisNodes[kMaxNodesInPath]; char16_t* fromNodes[kMaxNodesInPath]; int32_t thisNodeCnt, fromNodeCnt, nodeIndex; rv = GetPath(thisPath); if (NS_FAILED(rv)) { return rv; } rv = aFromFile->GetPath(fromPath); if (NS_FAILED(rv)) { return rv; } // get raw pointer to mutable string buffer char16_t* thisPathPtr; thisPath.BeginWriting(thisPathPtr); char16_t* fromPathPtr; fromPath.BeginWriting(fromPathPtr); thisNodeCnt = SplitPath(thisPathPtr, thisNodes, kMaxNodesInPath); fromNodeCnt = SplitPath(fromPathPtr, fromNodes, kMaxNodesInPath); if (thisNodeCnt < 0 || fromNodeCnt < 0) { return NS_ERROR_FAILURE; } for (nodeIndex = 0; nodeIndex < thisNodeCnt && nodeIndex < fromNodeCnt; ++nodeIndex) { #ifdef XP_WIN if (_wcsicmp(char16ptr_t(thisNodes[nodeIndex]), char16ptr_t(fromNodes[nodeIndex]))) { break; } #else if (nsCRT::strcmp(thisNodes[nodeIndex], fromNodes[nodeIndex])) { break; } #endif } int32_t branchIndex = nodeIndex; for (nodeIndex = branchIndex; nodeIndex < fromNodeCnt; ++nodeIndex) { aResult.AppendLiteral("../"); } for (nodeIndex = branchIndex; nodeIndex < thisNodeCnt; nodeIndex++) { NS_ConvertUTF16toUTF8 nodeStr(thisNodes[nodeIndex]); aResult.Append(nodeStr); if (nodeIndex + 1 < thisNodeCnt) { aResult.Append('/'); } } return NS_OK; }
PlanStage* buildStages(const QuerySolution& qsol, const QuerySolutionNode* root, WorkingSet* ws) { if (STAGE_COLLSCAN == root->getType()) { const CollectionScanNode* csn = static_cast<const CollectionScanNode*>(root); CollectionScanParams params; params.ns = csn->name; params.tailable = csn->tailable; params.direction = (csn->direction == 1) ? CollectionScanParams::FORWARD : CollectionScanParams::BACKWARD; params.maxScan = csn->maxScan; return new CollectionScan(params, ws, csn->filter.get()); } else if (STAGE_IXSCAN == root->getType()) { const IndexScanNode* ixn = static_cast<const IndexScanNode*>(root); // // XXX XXX // Given that this grabs data from the catalog, we must do this inside of a lock. // We should change this to take a (ns, index key pattern) pair so that the params // don't involve any on-disk data, just descriptions thereof. // XXX XXX // Database* db = cc().database(); Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { warning() << "Can't ixscan null ns " << qsol.ns << endl; return NULL; } IndexScanParams params; params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern( ixn->indexKeyPattern ); if ( params.descriptor == NULL ) { warning() << "Can't find idx " << ixn->indexKeyPattern.toString() << "in ns " << qsol.ns << endl; return NULL; } params.bounds = ixn->bounds; params.direction = ixn->direction; params.maxScan = ixn->maxScan; params.addKeyMetadata = ixn->addKeyMetadata; return new IndexScan(params, ws, ixn->filter.get()); } else if (STAGE_FETCH == root->getType()) { const FetchNode* fn = static_cast<const FetchNode*>(root); PlanStage* childStage = buildStages(qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } return new FetchStage(ws, childStage, fn->filter.get()); } else if (STAGE_SORT == root->getType()) { const SortNode* sn = static_cast<const SortNode*>(root); PlanStage* childStage = buildStages(qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } SortStageParams params; params.pattern = sn->pattern; params.query = sn->query; params.limit = sn->limit; return new SortStage(params, ws, childStage); } else if (STAGE_PROJECTION == root->getType()) { const ProjectionNode* pn = static_cast<const ProjectionNode*>(root); PlanStage* childStage = buildStages(qsol, pn->children[0], ws); if (NULL == childStage) { return NULL; } return new ProjectionStage(pn->projection, pn->fullExpression, ws, childStage); } else if (STAGE_LIMIT == root->getType()) { const LimitNode* ln = static_cast<const LimitNode*>(root); PlanStage* childStage = buildStages(qsol, ln->children[0], ws); if (NULL == childStage) { return NULL; } return new LimitStage(ln->limit, ws, childStage); } else if (STAGE_SKIP == root->getType()) { const SkipNode* sn = static_cast<const SkipNode*>(root); PlanStage* childStage = buildStages(qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } return new SkipStage(sn->skip, ws, childStage); } else if (STAGE_AND_HASH == root->getType()) { const AndHashNode* ahn = static_cast<const AndHashNode*>(root); auto_ptr<AndHashStage> ret(new AndHashStage(ws, ahn->filter.get())); for (size_t i = 0; i < ahn->children.size(); ++i) { PlanStage* childStage = buildStages(qsol, ahn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_OR == root->getType()) { const OrNode * orn = static_cast<const OrNode*>(root); auto_ptr<OrStage> ret(new OrStage(ws, orn->dedup, orn->filter.get())); for (size_t i = 0; i < orn->children.size(); ++i) { PlanStage* childStage = buildStages(qsol, orn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_AND_SORTED == root->getType()) { const AndSortedNode* asn = static_cast<const AndSortedNode*>(root); auto_ptr<AndSortedStage> ret(new AndSortedStage(ws, asn->filter.get())); for (size_t i = 0; i < asn->children.size(); ++i) { PlanStage* childStage = buildStages(qsol, asn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_SORT_MERGE == root->getType()) { const MergeSortNode* msn = static_cast<const MergeSortNode*>(root); MergeSortStageParams params; params.dedup = msn->dedup; params.pattern = msn->sort; auto_ptr<MergeSortStage> ret(new MergeSortStage(params, ws)); for (size_t i = 0; i < msn->children.size(); ++i) { PlanStage* childStage = buildStages(qsol, msn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } return ret.release(); } else if (STAGE_GEO_2D == root->getType()) { const Geo2DNode* node = static_cast<const Geo2DNode*>(root); TwoDParams params; params.gq = node->gq; params.filter = node->filter.get(); params.indexKeyPattern = node->indexKeyPattern; params.ns = qsol.ns; return new TwoD(params, ws); } else if (STAGE_GEO_NEAR_2D == root->getType()) { const GeoNear2DNode* node = static_cast<const GeoNear2DNode*>(root); TwoDNearParams params; params.nearQuery = node->nq; params.ns = qsol.ns; params.indexKeyPattern = node->indexKeyPattern; params.filter = node->filter.get(); params.numWanted = node->numWanted; params.addPointMeta = node->addPointMeta; params.addDistMeta = node->addDistMeta; return new TwoDNear(params, ws); } else if (STAGE_GEO_NEAR_2DSPHERE == root->getType()) { const GeoNear2DSphereNode* node = static_cast<const GeoNear2DSphereNode*>(root); S2NearParams params; params.ns = qsol.ns; params.indexKeyPattern = node->indexKeyPattern; params.nearQuery = node->nq; params.baseBounds = node->baseBounds; params.filter = node->filter.get(); params.addPointMeta = node->addPointMeta; params.addDistMeta = node->addDistMeta; return new S2NearStage(params, ws); } else if (STAGE_TEXT == root->getType()) { const TextNode* node = static_cast<const TextNode*>(root); Database* db = cc().database(); Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { warning() << "null collection for text?"; return NULL; } vector<IndexDescriptor*> idxMatches; collection->getIndexCatalog()->findIndexByType("text", idxMatches); if (1 != idxMatches.size()) { warning() << "more than one text idx?"; return NULL; } IndexDescriptor* index = idxMatches[0]; const FTSAccessMethod* fam = static_cast<FTSAccessMethod*>( collection->getIndexCatalog()->getIndex( index ) ); TextStageParams params(fam->getSpec()); params.ns = qsol.ns; params.index = index; params.spec = fam->getSpec(); // XXX change getIndexPrefix to not look at BSONObj Status s = fam->getSpec().getIndexPrefix(qsol.filterData, ¶ms.indexPrefix); if (!s.isOK()) { warning() << "can't get text index prefix??"; return NULL; } StringData language = ("" == node->_language ? fam->getSpec().defaultLanguage().str().c_str() : node->_language); FTSQuery ftsq; Status parseStatus = ftsq.parse(node->_query, language); if (!parseStatus.isOK()) { warning() << "cant parse fts query"; return NULL; } params.query = ftsq; return new TextStage(params, ws, node->filter.get()); } else if (STAGE_SHARDING_FILTER == root->getType()) { const ShardingFilterNode* fn = static_cast<const ShardingFilterNode*>(root); PlanStage* childStage = buildStages(qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } return new ShardFilterStage(shardingState.getCollectionMetadata(qsol.ns), ws, childStage); } else if (STAGE_KEEP_MUTATIONS == root->getType()) { const KeepMutationsNode* km = static_cast<const KeepMutationsNode*>(root); PlanStage* childStage = buildStages(qsol, km->children[0], ws); if (NULL == childStage) { return NULL; } return new KeepMutationsStage(km->filter.get(), ws, childStage); } else if (STAGE_DISTINCT == root->getType()) { const DistinctNode* dn = static_cast<const DistinctNode*>(root); Database* db = cc().database(); Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { warning() << "Can't distinct-scan null ns " << qsol.ns << endl; return NULL; } DistinctParams params; params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern(dn->indexKeyPattern); params.direction = dn->direction; params.bounds = dn->bounds; params.fieldNo = dn->fieldNo; return new DistinctScan(params, ws); } else { mongoutils::str::stream ss; root->appendToString(&ss, 0); string nodeStr(ss); warning() << "Could not build exec tree for node " << nodeStr << endl; return NULL; } }