1
0
Fork 0

(K_)SHORTEST PATHS: Display correct directions in explainer/profiler (#9049)

This commit is contained in:
Markus Pfeiffer 2019-05-22 14:06:46 +00:00 committed by Michael Hackstein
parent 79258e072a
commit 44d15db812
3 changed files with 65 additions and 30 deletions

View File

@ -81,7 +81,7 @@ GraphNode::GraphNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
// Direction is already the correct Integer.
// Is not inserted by user but by enum.
TRI_edge_direction_e baseDirection = parseDirection(direction);
_defaultDirection = parseDirection(direction);
std::unordered_map<std::string, TRI_edge_direction_e> seenCollections;
@ -130,7 +130,7 @@ GraphNode::GraphNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
dir = parseDirection(col->getMember(0));
col = col->getMember(1);
} else {
dir = baseDirection;
dir = _defaultDirection;
}
std::string eColName = col->getString();
@ -219,7 +219,7 @@ GraphNode::GraphNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
if (ServerState::instance()->isRunningInCluster()) {
auto c = ci->getCollection(_vocbase->name(), n);
if (!c->isSmart()) {
addEdgeCollection(n, baseDirection);
addEdgeCollection(n, _defaultDirection);
} else {
std::vector<std::string> names;
if (_isSmart) {
@ -228,11 +228,11 @@ GraphNode::GraphNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
names = c->realNamesForRead();
}
for (auto const& name : names) {
addEdgeCollection(name, baseDirection);
addEdgeCollection(name, _defaultDirection);
}
}
} else {
addEdgeCollection(n, baseDirection);
addEdgeCollection(n, _defaultDirection);
}
}
@ -263,25 +263,30 @@ GraphNode::GraphNode(ExecutionPlan* plan, arangodb::velocypack::Slice const& bas
_options(nullptr),
_optionsBuilt(false),
_isSmart(false) {
auto uint64ToDir = [](uint64_t d) -> TRI_edge_direction_e {
switch (d) {
case 1:
return TRI_EDGE_IN;
case 2:
return TRI_EDGE_OUT;
case 0:
TRI_ASSERT(false);
default:
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"Invalid direction value");
break;
}
};
uint64_t dir = arangodb::basics::VelocyPackHelper::stringUInt64(base.get("defaultDirection"));
_defaultDirection = uint64ToDir(dir);
// Directions
VPackSlice dirList = base.get("directions");
for (auto const& it : VPackArrayIterator(dirList)) {
uint64_t dir = arangodb::basics::VelocyPackHelper::stringUInt64(it);
TRI_edge_direction_e d;
switch (dir) {
case 1:
d = TRI_EDGE_IN;
break;
case 2:
d = TRI_EDGE_OUT;
break;
case 0:
TRI_ASSERT(false);
default:
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"Invalid direction value");
break;
}
TRI_edge_direction_e d = uint64ToDir(dir);
_directions.emplace_back(d);
}
@ -418,6 +423,9 @@ void GraphNode::toVelocyPackHelper(VPackBuilder& nodes, unsigned flags) const {
_graphObj->toVelocyPack(nodes);
}
// Default Direction
nodes.add("defaultDirection", VPackValue(_defaultDirection));
// Directions
nodes.add(VPackValue("directions"));
{

View File

@ -163,6 +163,9 @@ class GraphNode : public ExecutionNode {
/// @brief the vertex collection names
std::vector<std::unique_ptr<aql::Collection>> _vertexColls;
/// @brief The default direction given in the query
TRI_edge_direction_e _defaultDirection;
/// @brief The directions edges are followed
std::vector<TRI_edge_direction_e> _directions;

View File

@ -1260,7 +1260,7 @@ function processQuery(query, explain, planIndex) {
parts.push(variableName(node.edgeOutVariable) + ' ' + annotation('/* edge */'));
}
translate = ['ANY', 'INBOUND', 'OUTBOUND'];
let defaultDirection = node.directions[0];
let defaultDirection = node.defaultDirection;
rc = `${keyword("FOR")} ${parts.join(", ")} ${keyword("IN")} ${keyword(translate[defaultDirection])} ${keyword("SHORTEST_PATH")} `;
if (node.hasOwnProperty('startVertexId')) {
rc += `'${value(node.startVertexId)}'`;
@ -1277,13 +1277,25 @@ function processQuery(query, explain, planIndex) {
rc += ` ${annotation("/* targetnode */")} `;
if (Array.isArray(node.graph)) {
rc += node.graph.map(function (g, index) {
var directions = [], d;
for (var i = 0; i < node.edgeCollections.length; ++i) {
var isLast = (i + 1 === node.edgeCollections.length);
d = node.directions[i];
if (!isLast && node.edgeCollections[i] === node.edgeCollections[i + 1]) {
// direction ANY is represented by two traversals: an INBOUND and an OUTBOUND traversal
// on the same collection
d = 0; // ANY
++i;
}
directions.push({ collection: node.edgeCollections[i], direction: d });
}
rc += directions.map(function (g, index) {
var tmp = '';
if (node.directions[index] !== defaultDirection) {
tmp += keyword(translate[node.directions[index]]);
if (g.direction !== defaultDirection) {
tmp += keyword(translate[g.direction]);
tmp += ' ';
}
return tmp + collection(g);
return tmp + collection(g.collection);
}).join(', ');
} else {
rc += keyword('GRAPH') + " '" + value(node.graph) + "'";
@ -1320,7 +1332,7 @@ function processQuery(query, explain, planIndex) {
parts.push(variableName(node.pathOutVariable) + ' ' + annotation('/* path */'));
}
translate = ['ANY', 'INBOUND', 'OUTBOUND'];
let defaultDirection = node.directions[0];
let defaultDirection = node.defaultDirection;
rc = `${keyword("FOR")} ${parts.join(", ")} ${keyword("IN")} ${keyword(translate[defaultDirection])} ${keyword("K_SHORTEST_PATHS")} `;
if (node.hasOwnProperty('startVertexId')) {
rc += `'${value(node.startVertexId)}'`;
@ -1337,13 +1349,25 @@ function processQuery(query, explain, planIndex) {
rc += ` ${annotation("/* targetnode */")} `;
if (Array.isArray(node.graph)) {
rc += node.graph.map(function (g, index) {
var directions = [], d;
for (var i = 0; i < node.edgeCollections.length; ++i) {
var isLast = (i + 1 === node.edgeCollections.length);
d = node.directions[i];
if (!isLast && node.edgeCollections[i] === node.edgeCollections[i + 1]) {
// direction ANY is represented by two traversals: an INBOUND and an OUTBOUND traversal
// on the same collection
d = 0; // ANY
++i;
}
directions.push({ collection: node.edgeCollections[i], direction: d });
}
rc += directions.map(function (g, index) {
var tmp = '';
if (node.directions[index] !== defaultDirection) {
tmp += keyword(translate[node.directions[index]]);
if (g.direction !== defaultDirection) {
tmp += keyword(translate[g.direction]);
tmp += ' ';
}
return tmp + collection(g);
return tmp + collection(g.collection);
}).join(', ');
} else {
rc += keyword('GRAPH') + " '" + value(node.graph) + "'";