1
0
Fork 0

Implement tests for de/serializing of TraversalNodes.

This commit is contained in:
Wilfried Goesgens 2015-12-14 18:07:04 +01:00
parent 1b86f280de
commit f51e5efb34
4 changed files with 228 additions and 24 deletions

View File

@ -1501,7 +1501,8 @@ triagens::arango::TransactionContext* Query::createTransactionContext () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a TransactionContext
/// @brief look up a graph either from our cache list or from the _graphs
/// collection
////////////////////////////////////////////////////////////////////////////////
Graph const* Query::lookupGraphByName (std::string &name) {
@ -1517,7 +1518,6 @@ Graph const* Query::lookupGraphByName (std::string &name) {
return g;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -485,7 +485,7 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a TransactionContext
/// @brief look up a graph in the _graphs collection
////////////////////////////////////////////////////////////////////////////////
Graph const* lookupGraphByName (std::string &name);

View File

@ -44,6 +44,7 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
_edgeOutVariable(nullptr),
_pathOutVariable(nullptr),
_graphObj(nullptr),
_CalculationNodeId(0),
_condition(nullptr)
{
TRI_ASSERT(_vocbase != nullptr);
@ -175,7 +176,8 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
_minDepth(minDepth),
_maxDepth(maxDepth),
_direction(direction),
_condition(nullptr) {
_CalculationNodeId(0),
_condition(nullptr) {
for (auto& it : edgeColls) {
_edgeColls.push_back(it);
}
@ -200,13 +202,13 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
_direction = TRI_EDGE_ANY;
break;
case 1:
_direction = TRI_EDGE_OUT;
break;
case 2:
_direction = TRI_EDGE_IN;
break;
case 2:
_direction = TRI_EDGE_OUT;
break;
default:
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "unsupported 'direction'");
break;
}
@ -215,17 +217,54 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
_inVariable = varFromJson(plan->getAst(), base, "inVariable");
}
else {
triagens::basics::JsonHelper::getStringValue(base.json(), "vertexId", _vertexId);
_vertexId = triagens::basics::JsonHelper::getStringValue(base.json(), "vertexId", "");
if (_vertexId.size() == 0) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "start vertex mustn't be empty.");
}
}
TRI_json_t const* condition = JsonHelper::checkAndGetObjectValue(base.json(), "condition");
if (base.has("condition")) {
TRI_json_t const* condition = JsonHelper::checkAndGetObjectValue(base.json(), "condition");
if (condition != nullptr) {
triagens::basics::Json conditionJson(TRI_UNKNOWN_MEM_ZONE, condition, triagens::basics::Json::NOFREE);
_condition = Condition::fromJson(plan, conditionJson);
if (condition != nullptr) {
triagens::basics::Json conditionJson(TRI_UNKNOWN_MEM_ZONE, condition, triagens::basics::Json::NOFREE);
_condition = Condition::fromJson(plan, conditionJson);
}
}
std::string graphName;
if (base.has("graph") && (base.get("graph").isString())) {
graphName = JsonHelper::checkAndGetStringValue(base.json(), "graph");
if (base.has("graphDefinition")) {
_graphObj = plan->getAst()->query()->lookupGraphByName(graphName);
auto eColls = _graphObj->edgeCollections();
for (const auto& n: eColls) {
_edgeColls.push_back(n);
}
}
else {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "missing graphDefinition.");
}
}
else {
_condition = nullptr;
_graphJson = base.get("graph").copy();
if (!_graphJson.isArray()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "graph has to be an array.");
}
size_t edgeCollectionCount = _graphJson.size();
// List of edge collection names
for (size_t i = 0; i < edgeCollectionCount; ++i) {
auto at = _graphJson.at(i);
if (!at.isString()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "graph has to be an array of strings.");
}
_edgeColls.push_back(at.json()->_value._string.data);
}
if (_edgeColls.size() == 0) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_BAD_JSON_PLAN, "graph has to be a non empty array of strings.");
}
}
// Out variables

View File

@ -1,5 +1,5 @@
/*jshint esnext: true */
/*global assertEqual, fail, AQL_EXECUTE*/
/*global assertEqual, fail, AQL_EXECUTE, AQL_EXPLAIN, AQL_EXECUTEJSON */
////////////////////////////////////////////////////////////////////////////////
/// @brief Spec for the AQL FOR x IN GRAPH name statement
@ -39,6 +39,7 @@ const gm = require("org/arangodb/general-graph");
const vn = "UnitTestVertexCollection";
const en = "UnitTestEdgeCollection";
const isCluster = require("org/arangodb/cluster").isCluster();
var _ = require("underscore");
var vertex = {};
var edge = {};
var vc;
@ -74,9 +75,9 @@ function namedGraphSuite () {
/***********************************************************************
* Graph under test:
*
* A -> B -> C -> D
* /|\ \|/
* E <- F
* A -> B -> C -> D
* /|\ \|/
* E <- F
*
*
*
@ -94,10 +95,15 @@ function namedGraphSuite () {
var g;
const gn = "UnitTestGraph";
var ruleName = "merge-traversal-filter";
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
var opts = _.clone(paramEnabled);
return {
setUp: function() {
opts.allPlans = true;
opts.verbosePlans = true;
cleanup();
createBaseGraph();
try {
@ -122,6 +128,11 @@ function namedGraphSuite () {
var result = db._query(query, bindVars).toArray();
assertEqual(result.length, 1);
assertEqual(result[0]._id, vertex.C);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSecondEntryIsEdge: function () {
@ -133,6 +144,11 @@ function namedGraphSuite () {
var result = db._query(query, bindVars).toArray();
assertEqual(result.length, 1);
assertEqual(result[0]._id, edge.BC);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testThirdEntryIsPath: function () {
@ -149,6 +165,11 @@ function namedGraphSuite () {
assertEqual(entry.vertices[1]._id, vertex.C);
assertEqual(entry.edges.length, 1);
assertEqual(entry.edges[0]._id, edge.BC);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testOutboundDirection: function () {
@ -161,6 +182,11 @@ function namedGraphSuite () {
assertEqual(result.length, 1);
var entry = result[0];
assertEqual(entry, vertex.C);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testInboundDirection: function () {
@ -173,6 +199,11 @@ function namedGraphSuite () {
assertEqual(result.length, 1);
var entry = result[0];
assertEqual(entry, vertex.B);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testAnyDirection: function () {
@ -189,6 +220,11 @@ function namedGraphSuite () {
assertEqual(entry, vertex.C);
entry = result[2];
assertEqual(entry, vertex.E);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testExactNumberSteps: function () {
@ -202,6 +238,11 @@ function namedGraphSuite () {
assertEqual(result[0], vertex.D);
assertEqual(result[1], vertex.F);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testRangeNumberSteps: function () {
@ -216,6 +257,11 @@ function namedGraphSuite () {
assertEqual(result[0], vertex.D);
assertEqual(result[1], vertex.E);
assertEqual(result[2], vertex.F);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testComputedNumberSteps: function () {
@ -228,6 +274,11 @@ function namedGraphSuite () {
assertEqual(result.length, 2);
assertEqual(result[0], vertex.D);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSort: function () {
@ -249,8 +300,12 @@ function namedGraphSuite () {
assertEqual(result.length, 2);
assertEqual(result[0], vertex.F);
assertEqual(result[1], vertex.D);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
}
};
}
@ -271,6 +326,9 @@ function multiCollectionGraphSuite () {
const gn = "UnitTestGraph";
const vn2 = "UnitTestVertexCollection2";
const en2 = "UnitTestEdgeCollection2";
var ruleName = "merge-traversal-filter";
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
var opts = _.clone(paramEnabled);
// We always use the same query, the result should be identical.
var validateResult = function (result) {
@ -287,6 +345,8 @@ function multiCollectionGraphSuite () {
return {
setUp: function() {
opts.allPlans = true;
opts.verbosePlans = true;
cleanup();
try {
gm._drop(gn);
@ -310,7 +370,13 @@ function multiCollectionGraphSuite () {
testNoBindParameter: function () {
var query = "FOR x, e, p IN OUTBOUND '" + vertex.B + "' " + en + " RETURN {vertex: x, path: p}";
validateResult(db._query(query).toArray());
var result = db._query(query).toArray();
validateResult(result);
var plans = AQL_EXPLAIN(query, { }, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testStartBindParameter: function () {
@ -318,7 +384,13 @@ function multiCollectionGraphSuite () {
var bindVars = {
startId: vertex.B
};
validateResult(db._query(query, bindVars).toArray());
var result = db._query(query, bindVars).toArray();
validateResult(result);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testEdgeCollectionBindParameter: function () {
@ -326,7 +398,13 @@ function multiCollectionGraphSuite () {
var bindVars = {
"@eCol": en
};
validateResult(db._query(query, bindVars).toArray());
var result = db._query(query, bindVars).toArray();
validateResult(result);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testStepsBindParameter: function () {
@ -334,7 +412,13 @@ function multiCollectionGraphSuite () {
var bindVars = {
steps: 1
};
validateResult(db._query(query, bindVars).toArray());
var result = db._query(query, bindVars).toArray();
validateResult(result);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testStepsRangeBindParameter: function () {
@ -344,7 +428,13 @@ function multiCollectionGraphSuite () {
lsteps: 1,
rsteps: 1
};
validateResult(db._query(query, bindVars).toArray());
var result = db._query(query, bindVars).toArray();
validateResult(result);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testFirstEntryIsVertex: function () {
@ -356,6 +446,11 @@ function multiCollectionGraphSuite () {
var result = db._query(query, bindVars).toArray();
assertEqual(result.length, 1);
assertEqual(result[0]._id, vertex.C);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSecondEntryIsEdge: function () {
@ -367,6 +462,11 @@ function multiCollectionGraphSuite () {
var result = db._query(query, bindVars).toArray();
assertEqual(result.length, 1);
assertEqual(result[0]._id, edge.BC);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testThirdEntryIsPath: function () {
@ -383,6 +483,11 @@ function multiCollectionGraphSuite () {
assertEqual(entry.vertices[1]._id, vertex.C);
assertEqual(entry.edges.length, 1);
assertEqual(entry.edges[0]._id, edge.BC);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testOutboundDirection: function () {
@ -395,6 +500,11 @@ function multiCollectionGraphSuite () {
assertEqual(result.length, 1);
var entry = result[0];
assertEqual(entry, vertex.C);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testInboundDirection: function () {
@ -407,6 +517,11 @@ function multiCollectionGraphSuite () {
assertEqual(result.length, 1);
var entry = result[0];
assertEqual(entry, vertex.B);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testAnyDirection: function () {
@ -423,6 +538,11 @@ function multiCollectionGraphSuite () {
assertEqual(entry, vertex.C);
entry = result[2];
assertEqual(entry, vertex.E);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testExactNumberSteps: function () {
@ -436,6 +556,11 @@ function multiCollectionGraphSuite () {
assertEqual(result[0], vertex.D);
assertEqual(result[1], vertex.F);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testRangeNumberSteps: function () {
@ -450,6 +575,11 @@ function multiCollectionGraphSuite () {
assertEqual(result[0], vertex.D);
assertEqual(result[1], vertex.E);
assertEqual(result[2], vertex.F);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testComputedNumberSteps: function () {
@ -462,6 +592,11 @@ function multiCollectionGraphSuite () {
assertEqual(result.length, 2);
assertEqual(result[0], vertex.D);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSort: function () {
@ -483,6 +618,11 @@ function multiCollectionGraphSuite () {
assertEqual(result.length, 2);
assertEqual(result[0], vertex.F);
assertEqual(result[1], vertex.D);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSingleDocumentInput: function () {
@ -496,6 +636,11 @@ function multiCollectionGraphSuite () {
var result = db._query(query, bindVars).toArray();
assertEqual(result.length, 1);
assertEqual(result[0]._id, vertex.C);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testListDocumentInput: function () {
@ -513,6 +658,11 @@ function multiCollectionGraphSuite () {
assertEqual(result[3], vertex.D);
assertEqual(result[4], vertex.E);
assertEqual(result[5], vertex.F);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
};
@ -672,10 +822,15 @@ function potentialErrorsSuite () {
}
function complexInternaSuite () {
var ruleName = "merge-traversal-filter";
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
var opts = _.clone(paramEnabled);
return {
setUp: function () {
opts.allPlans = true;
opts.verbosePlans = true;
cleanup();
createBaseGraph();
},
@ -733,6 +888,11 @@ function complexInternaSuite () {
var result = db._query(query, bindVars).toArray();
// Internally: The Query selects elements in chunks, check that nothing is lost.
assertEqual(result.length, amount);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testSkipSome: function () {
@ -769,6 +929,11 @@ function complexInternaSuite () {
}
}
assertEqual(Object.keys(seen).length, 2);
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
plans.forEach(function(plan) {
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
assertEqual(jsonResult, result, query);
});
},
testManyResults: function () {