diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index ac51170123..83ad3d1099 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -2405,13 +2405,17 @@ AggregateBlock::AggregateBlock (ExecutionEngine* engine, } // iterate over all our variables - for (auto it = en->getRegisterPlan()->varInfo.begin(); - it != en->getRegisterPlan()->varInfo.end(); ++it) { - // find variable in the global variable map - auto itVar = en->_variableMap.find((*it).first); + for (auto& vi : en->getRegisterPlan()->varInfo) { + if (vi.second.depth > 0 || en->getDepth() == 1) { + // Do not keep variables from depth 0, unless we are depth 1 ourselves + // (which means no FOR in which we are contained) + + // find variable in the global variable map + auto itVar = en->_variableMap.find(vi.first); - if (itVar != en->_variableMap.end()) { - _variableNames[(*it).second.registerId] = (*itVar).second; + if (itVar != en->_variableMap.end()) { + _variableNames[vi.second.registerId] = (*itVar).second; + } } } } diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 096bb5dc73..a69bb6e8a4 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -2043,22 +2043,35 @@ ExecutionNode* AggregateNode::clone (ExecutionPlan* plan, //////////////////////////////////////////////////////////////////////////////// struct UserVarFinder : public WalkerWorker { - UserVarFinder () {}; + UserVarFinder (int mindepth) : mindepth(mindepth), depth(-1) {}; ~UserVarFinder () {}; std::vector userVars; + int mindepth; // minimal depth to consider + int depth; bool enterSubquery (ExecutionNode*, ExecutionNode*) override final { return false; } - bool before (ExecutionNode* en) override final { - auto vars = en->getVariablesSetHere(); - for (auto v : vars) { - if (v->isUserDefined()) { - userVars.push_back(v); + void after (ExecutionNode* en) override final { + if (en->getType() == ExecutionNode::SINGLETON) { + depth = 0; + } + else if (en->getType() == ExecutionNode::ENUMERATE_COLLECTION || + en->getType() == ExecutionNode::INDEX_RANGE || + en->getType() == ExecutionNode::ENUMERATE_LIST || + en->getType() == ExecutionNode::AGGREGATE) { + depth += 1; + } + // Now depth is set correct for this node. + if (depth >= mindepth) { + auto vars = en->getVariablesSetHere(); + for (auto v : vars) { + if (v->isUserDefined()) { + userVars.push_back(v); + } } } - return false; } }; @@ -2069,10 +2082,18 @@ std::vector AggregateNode::getVariablesUsedHere () const { } if (_outVariable != nullptr) { // Here we have to find all user defined variables in this query - // amonst our dependencies: - UserVarFinder finder; + // amongst our dependencies: + UserVarFinder finder(1); auto myselfasnonconst = const_cast(this); myselfasnonconst->walk(&finder); + if (finder.depth == 1) { + // we are toplevel, let's run again with mindepth = 0 + finder.userVars.clear(); + finder.mindepth = 0; + finder.depth = -1; + finder.reset(); + myselfasnonconst->walk(&finder); + } for (auto x : finder.userVars) { v.insert(x); }