1
0
Fork 0

Only put non-toplevel vars into the INTO variable in a COLLECT.

This restores the behaviour of 2.2.
This commit is contained in:
Max Neunhoeffer 2014-11-28 13:05:15 +01:00 committed by Frank Celler
parent 4d97f7a3ba
commit 5e3a41dabf
2 changed files with 40 additions and 15 deletions

View File

@ -2405,13 +2405,17 @@ AggregateBlock::AggregateBlock (ExecutionEngine* engine,
} }
// iterate over all our variables // iterate over all our variables
for (auto it = en->getRegisterPlan()->varInfo.begin(); for (auto& vi : en->getRegisterPlan()->varInfo) {
it != en->getRegisterPlan()->varInfo.end(); ++it) { if (vi.second.depth > 0 || en->getDepth() == 1) {
// find variable in the global variable map // Do not keep variables from depth 0, unless we are depth 1 ourselves
auto itVar = en->_variableMap.find((*it).first); // (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()) { if (itVar != en->_variableMap.end()) {
_variableNames[(*it).second.registerId] = (*itVar).second; _variableNames[vi.second.registerId] = (*itVar).second;
}
} }
} }
} }

View File

@ -2043,22 +2043,35 @@ ExecutionNode* AggregateNode::clone (ExecutionPlan* plan,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct UserVarFinder : public WalkerWorker<ExecutionNode> { struct UserVarFinder : public WalkerWorker<ExecutionNode> {
UserVarFinder () {}; UserVarFinder (int mindepth) : mindepth(mindepth), depth(-1) {};
~UserVarFinder () {}; ~UserVarFinder () {};
std::vector<Variable const*> userVars; std::vector<Variable const*> userVars;
int mindepth; // minimal depth to consider
int depth;
bool enterSubquery (ExecutionNode*, ExecutionNode*) override final { bool enterSubquery (ExecutionNode*, ExecutionNode*) override final {
return false; return false;
} }
bool before (ExecutionNode* en) override final { void after (ExecutionNode* en) override final {
auto vars = en->getVariablesSetHere(); if (en->getType() == ExecutionNode::SINGLETON) {
for (auto v : vars) { depth = 0;
if (v->isUserDefined()) { }
userVars.push_back(v); 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<Variable const*> AggregateNode::getVariablesUsedHere () const {
} }
if (_outVariable != nullptr) { if (_outVariable != nullptr) {
// Here we have to find all user defined variables in this query // Here we have to find all user defined variables in this query
// amonst our dependencies: // amongst our dependencies:
UserVarFinder finder; UserVarFinder finder(1);
auto myselfasnonconst = const_cast<AggregateNode*>(this); auto myselfasnonconst = const_cast<AggregateNode*>(this);
myselfasnonconst->walk(&finder); 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) { for (auto x : finder.userVars) {
v.insert(x); v.insert(x);
} }