1
0
Fork 0

fix 3-way joins (#9051)

This commit is contained in:
Jan 2019-05-21 17:33:50 +02:00 committed by GitHub
parent ac5d7efcb0
commit 7ec209fc74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 0 deletions

View File

@ -1,6 +1,9 @@
v3.4.6 (2016-05-21)
-------------------
* fixed "collection not found" exception during setup of 3-way smart join queries in the
cluster
* fixed an edge case of handling `null` values in the AQL function `MIN` for input
sequences that started with a `null` value. In this case, `null` was always returned as the
minimum value even though other non-null values may have followed, and `MIN` was supposed

View File

@ -266,6 +266,22 @@ void EngineInfoContainerDBServer::EngineInfo::serializeSnippet(
infoBuilder.add(VPackValue(arangodb::basics::StringUtils::itoa(_idOfRemoteNode) + ":" + id));
TRI_ASSERT(!_nodes.empty());
// build up a map of prototypes, e.g. c1 => c2, c2 => c3, c3 => c4,
// so we can determine a common prototype ancestor in case we have 3- or 4-way joins
std::unordered_map<aql::Collection const*, aql::Collection const*> prototypes;
for (auto enIt = _nodes.rbegin(), end = _nodes.rend(); enIt != end; ++enIt) {
auto const nodeType = (*enIt)->getType();
if (nodeType == ExecutionNode::INDEX || nodeType == ExecutionNode::ENUMERATE_COLLECTION) {
auto x = dynamic_cast<CollectionAccessingNode*>(*enIt);
auto const* prototype = x->prototypeCollection();
if (prototype == nullptr) {
continue;
}
prototypes[x->collection()] = prototype;
}
}
// copy the relevant fragment of the plan for each shard
// Note that in these parts of the query there are no SubqueryNodes,
// since they are all on the coordinator!
@ -292,6 +308,15 @@ void EngineInfoContainerDBServer::EngineInfo::serializeSnippet(
if (nodeType == ExecutionNode::INDEX || nodeType == ExecutionNode::ENUMERATE_COLLECTION) {
auto x = dynamic_cast<CollectionAccessingNode*>(clone);
auto const* prototype = x->prototypeCollection();
// find prototypes of prototypes
while (prototype != nullptr) {
auto it = prototypes.find(prototype);
if (it == prototypes.end()) {
break;
}
prototype = (*it).second;
}
if (prototype != nullptr) {
auto s1 = prototype->shardIds();
auto s2 = x->collection()->shardIds();