1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Frank Celler 2014-10-20 10:12:35 +02:00
commit 1cdf01970e
9 changed files with 2009 additions and 1279 deletions

View File

@ -571,7 +571,7 @@ int SingletonBlock::getOrSkipSome (size_t, // atLeast,
} }
if(! skipping){ if(! skipping){
result = new AqlItemBlock(1, getPlanNode()->getVarOverview()->nrRegs[getPlanNode()->getDepth()]); result = new AqlItemBlock(1, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]);
try { try {
if (_inputRegisterValues != nullptr) { if (_inputRegisterValues != nullptr) {
skipped++; skipped++;
@ -697,7 +697,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome (size_t, // atLeast,
size_t available = _documents.size() - _posInAllDocs; size_t available = _documents.size() - _posInAllDocs;
size_t toSend = (std::min)(atMost, available); size_t toSend = (std::min)(atMost, available);
unique_ptr<AqlItemBlock> res(new AqlItemBlock(toSend, getPlanNode()->getVarOverview()->nrRegs[getPlanNode()->getDepth()])); unique_ptr<AqlItemBlock> res(new AqlItemBlock(toSend, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]));
// automatically freed if we throw // automatically freed if we throw
TRI_ASSERT(curRegs <= res->getNrRegs()); TRI_ASSERT(curRegs <= res->getNrRegs());
@ -718,7 +718,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome (size_t, // atLeast,
} }
// The result is in the first variable of this depth, // The result is in the first variable of this depth,
// we do not need to do a lookup in getPlanNode()->_varOverview->varInfo, // we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo,
// but can just take cur->getNrRegs() as registerId: // but can just take cur->getNrRegs() as registerId:
res->setValue(j, static_cast<triagens::aql::RegisterId>(curRegs), res->setValue(j, static_cast<triagens::aql::RegisterId>(curRegs),
AqlValue(reinterpret_cast<TRI_df_marker_t AqlValue(reinterpret_cast<TRI_df_marker_t
@ -855,8 +855,8 @@ int IndexRangeBlock::initialize () {
std::unordered_set<Variable*> inVars = e->variables(); std::unordered_set<Variable*> inVars = e->variables();
for (auto v : inVars) { for (auto v : inVars) {
inVarsCur.push_back(v); inVarsCur.push_back(v);
auto it = getPlanNode()->getVarOverview()->varInfo.find(v->id); auto it = getPlanNode()->getRegisterPlan()->varInfo.find(v->id);
TRI_ASSERT(it != getPlanNode()->getVarOverview()->varInfo.end()); TRI_ASSERT(it != getPlanNode()->getRegisterPlan()->varInfo.end());
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
inRegsCur.push_back(it->second.registerId); inRegsCur.push_back(it->second.registerId);
} }
@ -1062,7 +1062,7 @@ AqlItemBlock* IndexRangeBlock::getSome (size_t, // atLeast
if (toSend > 0) { if (toSend > 0) {
res.reset(new AqlItemBlock(toSend, getPlanNode()->getVarOverview()->nrRegs[getPlanNode()->getDepth()])); res.reset(new AqlItemBlock(toSend, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]));
// automatically freed should we throw // automatically freed should we throw
TRI_ASSERT(curRegs <= res->getNrRegs()); TRI_ASSERT(curRegs <= res->getNrRegs());
@ -1084,7 +1084,7 @@ AqlItemBlock* IndexRangeBlock::getSome (size_t, // atLeast
} }
// The result is in the first variable of this depth, // The result is in the first variable of this depth,
// we do not need to do a lookup in getPlanNode()->_varOverview->varInfo, // we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo,
// but can just take cur->getNrRegs() as registerId: // but can just take cur->getNrRegs() as registerId:
res->setValue(j, static_cast<triagens::aql::RegisterId>(curRegs), res->setValue(j, static_cast<triagens::aql::RegisterId>(curRegs),
AqlValue(reinterpret_cast<TRI_df_marker_t AqlValue(reinterpret_cast<TRI_df_marker_t
@ -1506,8 +1506,8 @@ EnumerateListBlock::EnumerateListBlock (ExecutionEngine* engine,
: ExecutionBlock(engine, en), : ExecutionBlock(engine, en),
_inVarRegId(ExecutionNode::MaxRegisterId) { _inVarRegId(ExecutionNode::MaxRegisterId) {
auto it = en->getVarOverview()->varInfo.find(en->_inVariable->id); auto it = en->getRegisterPlan()->varInfo.find(en->_inVariable->id);
if (it == en->getVarOverview()->varInfo.end()){ if (it == en->getRegisterPlan()->varInfo.end()){
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "variable not found"); THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "variable not found");
} }
_inVarRegId = (*it).second.registerId; _inVarRegId = (*it).second.registerId;
@ -1620,7 +1620,7 @@ AqlItemBlock* EnumerateListBlock::getSome (size_t, size_t atMost) {
size_t toSend = (std::min)(atMost, sizeInVar - _index); size_t toSend = (std::min)(atMost, sizeInVar - _index);
// create the result // create the result
res.reset(new AqlItemBlock(toSend, getPlanNode()->getVarOverview()->nrRegs[getPlanNode()->getDepth()])); res.reset(new AqlItemBlock(toSend, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]));
inheritRegisters(cur, res.get(), _pos); inheritRegisters(cur, res.get(), _pos);
@ -1794,9 +1794,9 @@ CalculationBlock::CalculationBlock (ExecutionEngine* engine,
for (auto it = inVars.begin(); it != inVars.end(); ++it) { for (auto it = inVars.begin(); it != inVars.end(); ++it) {
_inVars.push_back(*it); _inVars.push_back(*it);
auto it2 = en->getVarOverview()->varInfo.find((*it)->id); auto it2 = en->getRegisterPlan()->varInfo.find((*it)->id);
TRI_ASSERT(it2 != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it2 != en->getRegisterPlan()->varInfo.end());
TRI_ASSERT(it2->second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT(it2->second.registerId < ExecutionNode::MaxRegisterId);
_inRegs.push_back(it2->second.registerId); _inRegs.push_back(it2->second.registerId);
} }
@ -1809,8 +1809,8 @@ CalculationBlock::CalculationBlock (ExecutionEngine* engine,
TRI_ASSERT(_inRegs.size() == 1); TRI_ASSERT(_inRegs.size() == 1);
} }
auto it3 = en->getVarOverview()->varInfo.find(en->_outVariable->id); auto it3 = en->getRegisterPlan()->varInfo.find(en->_outVariable->id);
TRI_ASSERT(it3 != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it3 != en->getRegisterPlan()->varInfo.end());
_outReg = it3->second.registerId; _outReg = it3->second.registerId;
TRI_ASSERT(_outReg < ExecutionNode::MaxRegisterId); TRI_ASSERT(_outReg < ExecutionNode::MaxRegisterId);
} }
@ -1905,8 +1905,8 @@ SubqueryBlock::SubqueryBlock (ExecutionEngine* engine,
_outReg(ExecutionNode::MaxRegisterId), _outReg(ExecutionNode::MaxRegisterId),
_subquery(subquery) { _subquery(subquery) {
auto it = en->getVarOverview()->varInfo.find(en->_outVariable->id); auto it = en->getRegisterPlan()->varInfo.find(en->_outVariable->id);
TRI_ASSERT(it != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
_outReg = it->second.registerId; _outReg = it->second.registerId;
TRI_ASSERT(_outReg < ExecutionNode::MaxRegisterId); TRI_ASSERT(_outReg < ExecutionNode::MaxRegisterId);
} }
@ -1973,8 +1973,8 @@ FilterBlock::FilterBlock (ExecutionEngine* engine,
: ExecutionBlock(engine, en), : ExecutionBlock(engine, en),
_inReg(ExecutionNode::MaxRegisterId) { _inReg(ExecutionNode::MaxRegisterId) {
auto it = en->getVarOverview()->varInfo.find(en->_inVariable->id); auto it = en->getRegisterPlan()->varInfo.find(en->_inVariable->id);
TRI_ASSERT(it != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
_inReg = it->second.registerId; _inReg = it->second.registerId;
TRI_ASSERT(_inReg < ExecutionNode::MaxRegisterId); TRI_ASSERT(_inReg < ExecutionNode::MaxRegisterId);
} }
@ -2154,33 +2154,33 @@ AggregateBlock::AggregateBlock (ExecutionEngine* engine,
for (auto p : en->_aggregateVariables) { for (auto p : en->_aggregateVariables) {
// We know that planRegisters() has been run, so // We know that planRegisters() has been run, so
// getPlanNode()->_varOverview is set up // getPlanNode()->_registerPlan is set up
auto itOut = en->getVarOverview()->varInfo.find(p.first->id); auto itOut = en->getRegisterPlan()->varInfo.find(p.first->id);
TRI_ASSERT(itOut != en->getVarOverview()->varInfo.end()); TRI_ASSERT(itOut != en->getRegisterPlan()->varInfo.end());
auto itIn = en->getVarOverview()->varInfo.find(p.second->id); auto itIn = en->getRegisterPlan()->varInfo.find(p.second->id);
TRI_ASSERT(itIn != en->getVarOverview()->varInfo.end()); TRI_ASSERT(itIn != en->getRegisterPlan()->varInfo.end());
TRI_ASSERT((*itIn).second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT((*itIn).second.registerId < ExecutionNode::MaxRegisterId);
TRI_ASSERT((*itOut).second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT((*itOut).second.registerId < ExecutionNode::MaxRegisterId);
_aggregateRegisters.emplace_back(make_pair((*itOut).second.registerId, (*itIn).second.registerId)); _aggregateRegisters.emplace_back(make_pair((*itOut).second.registerId, (*itIn).second.registerId));
} }
if (en->_outVariable != nullptr) { if (en->_outVariable != nullptr) {
auto it = en->getVarOverview()->varInfo.find(en->_outVariable->id); auto it = en->getRegisterPlan()->varInfo.find(en->_outVariable->id);
TRI_ASSERT(it != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
_groupRegister = (*it).second.registerId; _groupRegister = (*it).second.registerId;
TRI_ASSERT(_groupRegister > 0 && _groupRegister < ExecutionNode::MaxRegisterId); TRI_ASSERT(_groupRegister > 0 && _groupRegister < ExecutionNode::MaxRegisterId);
// construct a mapping of all register ids to variable names // construct a mapping of all register ids to variable names
// we need this mapping to generate the grouped output // we need this mapping to generate the grouped output
for (size_t i = 0; i < en->getVarOverview()->varInfo.size(); ++i) { for (size_t i = 0; i < en->getRegisterPlan()->varInfo.size(); ++i) {
_variableNames.push_back(""); // initialize with some default value _variableNames.push_back(""); // initialize with some default value
} }
// iterate over all our variables // iterate over all our variables
for (auto it = en->getVarOverview()->varInfo.begin(); for (auto it = en->getRegisterPlan()->varInfo.begin();
it != en->getVarOverview()->varInfo.end(); ++it) { it != en->getRegisterPlan()->varInfo.end(); ++it) {
// find variable in the global variable map // find variable in the global variable map
auto itVar = en->_variableMap.find((*it).first); auto itVar = en->_variableMap.find((*it).first);
@ -2239,7 +2239,7 @@ int AggregateBlock::getOrSkipSome (size_t atLeast,
unique_ptr<AqlItemBlock> res; unique_ptr<AqlItemBlock> res;
if (! skipping) { if (! skipping) {
res.reset(new AqlItemBlock(atMost, getPlanNode()->getVarOverview()->nrRegs[getPlanNode()->getDepth()])); res.reset(new AqlItemBlock(atMost, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]));
TRI_ASSERT(cur->getNrRegs() <= res->getNrRegs()); TRI_ASSERT(cur->getNrRegs() <= res->getNrRegs());
inheritRegisters(cur, res.get(), _pos); inheritRegisters(cur, res.get(), _pos);
@ -2402,8 +2402,8 @@ SortBlock::SortBlock (ExecutionEngine* engine,
_stable(en->_stable) { _stable(en->_stable) {
for (auto p : en->_elements) { for (auto p : en->_elements) {
auto it = en->getVarOverview()->varInfo.find(p.first->id); auto it = en->getRegisterPlan()->varInfo.find(p.first->id);
TRI_ASSERT(it != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
_sortRegisters.push_back(make_pair(it->second.registerId, p.second)); _sortRegisters.push_back(make_pair(it->second.registerId, p.second));
} }
@ -2698,8 +2698,8 @@ AqlItemBlock* ReturnBlock::getSome (size_t atLeast,
// Let's steal the actual result and throw away the vars: // Let's steal the actual result and throw away the vars:
auto ep = static_cast<ReturnNode const*>(getPlanNode()); auto ep = static_cast<ReturnNode const*>(getPlanNode());
auto it = ep->getVarOverview()->varInfo.find(ep->_inVariable->id); auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
RegisterId const registerId = it->second.registerId; RegisterId const registerId = it->second.registerId;
AqlItemBlock* stripped = new AqlItemBlock(n, 1); AqlItemBlock* stripped = new AqlItemBlock(n, 1);
@ -2852,8 +2852,8 @@ RemoveBlock::~RemoveBlock () {
void RemoveBlock::work (std::vector<AqlItemBlock*>& blocks) { void RemoveBlock::work (std::vector<AqlItemBlock*>& blocks) {
auto ep = static_cast<RemoveNode const*>(getPlanNode()); auto ep = static_cast<RemoveNode const*>(getPlanNode());
auto it = ep->getVarOverview()->varInfo.find(ep->_inVariable->id); auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
RegisterId const registerId = it->second.registerId; RegisterId const registerId = it->second.registerId;
auto trxCollection = _trx->trxCollection(_collection->cid()); auto trxCollection = _trx->trxCollection(_collection->cid());
@ -2929,8 +2929,8 @@ InsertBlock::~InsertBlock () {
void InsertBlock::work (std::vector<AqlItemBlock*>& blocks) { void InsertBlock::work (std::vector<AqlItemBlock*>& blocks) {
auto ep = static_cast<InsertNode const*>(getPlanNode()); auto ep = static_cast<InsertNode const*>(getPlanNode());
auto it = ep->getVarOverview()->varInfo.find(ep->_inVariable->id); auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
RegisterId const registerId = it->second.registerId; RegisterId const registerId = it->second.registerId;
auto trxCollection = _trx->trxCollection(_collection->cid()); auto trxCollection = _trx->trxCollection(_collection->cid());
@ -3041,16 +3041,16 @@ UpdateBlock::~UpdateBlock () {
void UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) { void UpdateBlock::work (std::vector<AqlItemBlock*>& blocks) {
auto ep = static_cast<UpdateNode const*>(getPlanNode()); auto ep = static_cast<UpdateNode const*>(getPlanNode());
auto it = ep->getVarOverview()->varInfo.find(ep->_inDocVariable->id); auto it = ep->getRegisterPlan()->varInfo.find(ep->_inDocVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
RegisterId const docRegisterId = it->second.registerId; RegisterId const docRegisterId = it->second.registerId;
RegisterId keyRegisterId = 0; // default initialization RegisterId keyRegisterId = 0; // default initialization
bool const hasKeyVariable = (ep->_inKeyVariable != nullptr); bool const hasKeyVariable = (ep->_inKeyVariable != nullptr);
if (hasKeyVariable) { if (hasKeyVariable) {
it = ep->getVarOverview()->varInfo.find(ep->_inKeyVariable->id); it = ep->getRegisterPlan()->varInfo.find(ep->_inKeyVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
keyRegisterId = it->second.registerId; keyRegisterId = it->second.registerId;
} }
@ -3159,16 +3159,16 @@ ReplaceBlock::~ReplaceBlock () {
void ReplaceBlock::work (std::vector<AqlItemBlock*>& blocks) { void ReplaceBlock::work (std::vector<AqlItemBlock*>& blocks) {
auto ep = static_cast<ReplaceNode const*>(getPlanNode()); auto ep = static_cast<ReplaceNode const*>(getPlanNode());
auto it = ep->getVarOverview()->varInfo.find(ep->_inDocVariable->id); auto it = ep->getRegisterPlan()->varInfo.find(ep->_inDocVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
RegisterId const registerId = it->second.registerId; RegisterId const registerId = it->second.registerId;
RegisterId keyRegisterId = 0; // default initialization RegisterId keyRegisterId = 0; // default initialization
bool const hasKeyVariable = (ep->_inKeyVariable != nullptr); bool const hasKeyVariable = (ep->_inKeyVariable != nullptr);
if (hasKeyVariable) { if (hasKeyVariable) {
it = ep->getVarOverview()->varInfo.find(ep->_inKeyVariable->id); it = ep->getRegisterPlan()->varInfo.find(ep->_inKeyVariable->id);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
keyRegisterId = it->second.registerId; keyRegisterId = it->second.registerId;
} }
@ -3265,9 +3265,9 @@ GatherBlock::GatherBlock (ExecutionEngine* engine,
if (! _isSimple) { if (! _isSimple) {
for (auto p : en->getElements()) { for (auto p : en->getElements()) {
// We know that planRegisters has been run, so // We know that planRegisters has been run, so
// getPlanNode()->_varOverview is set up // getPlanNode()->_registerPlan is set up
auto it = en->getVarOverview()->varInfo.find(p.first->id); auto it = en->getRegisterPlan()->varInfo.find(p.first->id);
TRI_ASSERT(it != en->getVarOverview()->varInfo.end()); TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId); TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
_sortRegisters.emplace_back(make_pair(it->second.registerId, p.second)); _sortRegisters.emplace_back(make_pair(it->second.registerId, p.second));
} }
@ -3974,8 +3974,8 @@ DistributeBlock::DistributeBlock (ExecutionEngine* engine,
VariableId varId = ep->_varId; VariableId varId = ep->_varId;
// get the register id of the variable to inspect . . . // get the register id of the variable to inspect . . .
auto it = ep->getVarOverview()->varInfo.find(varId); auto it = ep->getRegisterPlan()->varInfo.find(varId);
TRI_ASSERT(it != ep->getVarOverview()->varInfo.end()); TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
_regId = (*it).second.registerId; _regId = (*it).second.registerId;
} }

View File

@ -1684,13 +1684,15 @@ namespace triagens {
ScatterBlock (ExecutionEngine* engine, ScatterBlock (ExecutionEngine* engine,
ScatterNode const* ep, ScatterNode const* ep,
std::vector<std::string> const& shardIds) std::vector<std::string> const& shardIds)
: BlockWithClients(engine, ep, shardIds) {} : BlockWithClients(engine, ep, shardIds) {
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destructor /// @brief destructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
~ScatterBlock () {} ~ScatterBlock () {
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor /// @brief initializeCursor
@ -1755,7 +1757,8 @@ namespace triagens {
/// @brief destructor /// @brief destructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
~DistributeBlock () {} ~DistributeBlock () {
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief initializeCursor /// @brief initializeCursor

View File

@ -222,11 +222,11 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
_plan(plan), _plan(plan),
_depth(JsonHelper::checkAndGetNumericValue<int>(json.json(), "depth")) { _depth(JsonHelper::checkAndGetNumericValue<int>(json.json(), "depth")) {
TRI_ASSERT(_varOverview.get() == nullptr); TRI_ASSERT(_registerPlan.get() == nullptr);
_varOverview.reset(new VarOverview()); _registerPlan.reset(new RegisterPlan());
_varOverview->clear(); _registerPlan->clear();
_varOverview->depth = _depth; _registerPlan->depth = _depth;
_varOverview->totalNrRegs = JsonHelper::checkAndGetNumericValue<unsigned int>(json.json(), "totalNrRegs"); _registerPlan->totalNrRegs = JsonHelper::checkAndGetNumericValue<unsigned int>(json.json(), "totalNrRegs");
auto jsonVarInfoList = json.get("varInfoList"); auto jsonVarInfoList = json.get("varInfoList");
if (! jsonVarInfoList.isList()) { if (! jsonVarInfoList.isList()) {
@ -234,7 +234,7 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
} }
size_t len = jsonVarInfoList.size(); size_t len = jsonVarInfoList.size();
_varOverview->varInfo.reserve(len); _registerPlan->varInfo.reserve(len);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
auto jsonVarInfo = jsonVarInfoList.at(i); auto jsonVarInfo = jsonVarInfoList.at(i);
@ -245,7 +245,7 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
RegisterId registerId = JsonHelper::checkAndGetNumericValue<RegisterId> (jsonVarInfo.json(), "RegisterId"); RegisterId registerId = JsonHelper::checkAndGetNumericValue<RegisterId> (jsonVarInfo.json(), "RegisterId");
unsigned int depth = JsonHelper::checkAndGetNumericValue<unsigned int>(jsonVarInfo.json(), "depth"); unsigned int depth = JsonHelper::checkAndGetNumericValue<unsigned int>(jsonVarInfo.json(), "depth");
_varOverview->varInfo.emplace(make_pair(variableId, VarInfo(depth, registerId))); _registerPlan->varInfo.emplace(make_pair(variableId, VarInfo(depth, registerId)));
} }
auto jsonNrRegsList = json.get("nrRegs"); auto jsonNrRegsList = json.get("nrRegs");
@ -254,10 +254,10 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
} }
len = jsonNrRegsList.size(); len = jsonNrRegsList.size();
_varOverview->nrRegs.reserve(len); _registerPlan->nrRegs.reserve(len);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
RegisterId oneReg = JsonHelper::getNumericValue<RegisterId>(jsonNrRegsList.at(i).json(), 0); RegisterId oneReg = JsonHelper::getNumericValue<RegisterId>(jsonNrRegsList.at(i).json(), 0);
_varOverview->nrRegs.push_back(oneReg); _registerPlan->nrRegs.push_back(oneReg);
} }
auto jsonNrRegsHereList = json.get("nrRegsHere"); auto jsonNrRegsHereList = json.get("nrRegsHere");
@ -266,10 +266,10 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
} }
len = jsonNrRegsHereList.size(); len = jsonNrRegsHereList.size();
_varOverview->nrRegsHere.reserve(len); _registerPlan->nrRegsHere.reserve(len);
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
RegisterId oneReg = JsonHelper::getNumericValue<RegisterId>(jsonNrRegsHereList.at(i).json(), 0); RegisterId oneReg = JsonHelper::getNumericValue<RegisterId>(jsonNrRegsHereList.at(i).json(), 0);
_varOverview->nrRegsHere.push_back(oneReg); _registerPlan->nrRegsHere.push_back(oneReg);
} }
auto jsonRegsToClearList = json.get("regsToClear"); auto jsonRegsToClearList = json.get("regsToClear");
@ -375,9 +375,9 @@ void ExecutionNode::CloneHelper (ExecutionNode* other,
TRI_ASSERT(var != nullptr); TRI_ASSERT(var != nullptr);
other->_varsValid.insert(var); other->_varsValid.insert(var);
} }
if (_varOverview.get() != nullptr) { if (_registerPlan.get() != nullptr) {
auto othervarOverview = std::shared_ptr<VarOverview>(_varOverview->clone(plan, _plan)); auto otherRegisterPlan = std::shared_ptr<RegisterPlan>(_registerPlan->clone(plan, _plan));
other->_varOverview = othervarOverview; other->_registerPlan = otherRegisterPlan;
} }
} }
else { else {
@ -387,7 +387,7 @@ void ExecutionNode::CloneHelper (ExecutionNode* other,
other->_varUsageValid = _varUsageValid; other->_varUsageValid = _varUsageValid;
other->_varsUsedLater = _varsUsedLater; other->_varsUsedLater = _varsUsedLater;
other->_varsValid = _varsValid; other->_varsValid = _varsValid;
other->_varOverview = _varOverview; other->_registerPlan = _registerPlan;
} }
plan->registerNode(other); plan->registerNode(other);
@ -636,9 +636,9 @@ triagens::basics::Json ExecutionNode::toJsonHelperGeneric (triagens::basics::Jso
if (verbose) { if (verbose) {
json("depth", triagens::basics::Json(static_cast<double>(_depth))); json("depth", triagens::basics::Json(static_cast<double>(_depth)));
if (_varOverview) { if (_registerPlan) {
triagens::basics::Json jsonVarInfoList(triagens::basics::Json::List, _varOverview->varInfo.size()); triagens::basics::Json jsonVarInfoList(triagens::basics::Json::List, _registerPlan->varInfo.size());
for (auto oneVarInfo: _varOverview->varInfo) { for (auto oneVarInfo: _registerPlan->varInfo) {
triagens::basics::Json jsonOneVarInfoArray(triagens::basics::Json::Array, 2); triagens::basics::Json jsonOneVarInfoArray(triagens::basics::Json::Array, 2);
jsonOneVarInfoArray( jsonOneVarInfoArray(
"VariableId", "VariableId",
@ -650,18 +650,18 @@ triagens::basics::Json ExecutionNode::toJsonHelperGeneric (triagens::basics::Jso
} }
json("varInfoList", jsonVarInfoList); json("varInfoList", jsonVarInfoList);
triagens::basics::Json jsonNRRegsList(triagens::basics::Json::List, _varOverview->nrRegs.size()); triagens::basics::Json jsonNRRegsList(triagens::basics::Json::List, _registerPlan->nrRegs.size());
for (auto oneRegisterID: _varOverview->nrRegs) { for (auto oneRegisterID: _registerPlan->nrRegs) {
jsonNRRegsList(triagens::basics::Json(static_cast<double>(oneRegisterID))); jsonNRRegsList(triagens::basics::Json(static_cast<double>(oneRegisterID)));
} }
json("nrRegs", jsonNRRegsList); json("nrRegs", jsonNRRegsList);
triagens::basics::Json jsonNRRegsHereList(triagens::basics::Json::List, _varOverview->nrRegsHere.size()); triagens::basics::Json jsonNRRegsHereList(triagens::basics::Json::List, _registerPlan->nrRegsHere.size());
for (auto oneRegisterID: _varOverview->nrRegsHere) { for (auto oneRegisterID: _registerPlan->nrRegsHere) {
jsonNRRegsHereList(triagens::basics::Json(static_cast<double>(oneRegisterID))); jsonNRRegsHereList(triagens::basics::Json(static_cast<double>(oneRegisterID)));
} }
json("nrRegsHere", jsonNRRegsHereList); json("nrRegsHere", jsonNRRegsHereList);
json("totalNrRegs", triagens::basics::Json(static_cast<double>(_varOverview->totalNrRegs))); json("totalNrRegs", triagens::basics::Json(static_cast<double>(_registerPlan->totalNrRegs)));
} }
else { else {
json("varInfoList", triagens::basics::Json(triagens::basics::Json::List)); json("varInfoList", triagens::basics::Json(triagens::basics::Json::List));
@ -719,12 +719,12 @@ struct RegisterPlanningDebugger : public WalkerWorker<ExecutionNode> {
std::cout << ep->getTypeString() << " "; std::cout << ep->getTypeString() << " ";
std::cout << "regsUsedHere: "; std::cout << "regsUsedHere: ";
for (auto v : ep->getVariablesUsedHere()) { for (auto v : ep->getVariablesUsedHere()) {
std::cout << ep->getVarOverview()->varInfo.find(v->id)->second.registerId std::cout << ep->getRegisterPlan()->varInfo.find(v->id)->second.registerId
<< " "; << " ";
} }
std::cout << "regsSetHere: "; std::cout << "regsSetHere: ";
for (auto v : ep->getVariablesSetHere()) { for (auto v : ep->getVariablesSetHere()) {
std::cout << ep->getVarOverview()->varInfo.find(v->id)->second.registerId std::cout << ep->getRegisterPlan()->varInfo.find(v->id)->second.registerId
<< " "; << " ";
} }
std::cout << "regsToClear: "; std::cout << "regsToClear: ";
@ -742,12 +742,12 @@ struct RegisterPlanningDebugger : public WalkerWorker<ExecutionNode> {
void ExecutionNode::planRegisters (ExecutionNode* super) { void ExecutionNode::planRegisters (ExecutionNode* super) {
// std::cout << triagens::arango::ServerState::instance()->getId() << ": PLAN REGISTERS\n"; // std::cout << triagens::arango::ServerState::instance()->getId() << ": PLAN REGISTERS\n";
// The super is only for the case of subqueries. // The super is only for the case of subqueries.
shared_ptr<VarOverview> v; shared_ptr<RegisterPlan> v;
if (super == nullptr) { if (super == nullptr) {
v.reset(new VarOverview()); v.reset(new RegisterPlan());
} }
else { else {
v.reset(new VarOverview(*(super->_varOverview), super->_depth)); v.reset(new RegisterPlan(*(super->_registerPlan), super->_depth));
} }
v->setSharedPtr(&v); v->setSharedPtr(&v);
@ -769,11 +769,11 @@ void ExecutionNode::planRegisters (ExecutionNode* super) {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- struct ExecutionNode::VarOverview // --SECTION-- struct ExecutionNode::RegisterPlan
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Copy constructor used for a subquery: // Copy constructor used for a subquery:
ExecutionNode::VarOverview::VarOverview (VarOverview const& v, ExecutionNode::RegisterPlan::RegisterPlan (RegisterPlan const& v,
unsigned int newdepth) unsigned int newdepth)
: varInfo(v.varInfo), : varInfo(v.varInfo),
nrRegsHere(v.nrRegsHere), nrRegsHere(v.nrRegsHere),
@ -788,7 +788,7 @@ ExecutionNode::VarOverview::VarOverview (VarOverview const& v,
nrRegs.push_back(nrRegs.back()); nrRegs.push_back(nrRegs.back());
} }
void ExecutionNode::VarOverview::clear () { void ExecutionNode::RegisterPlan::clear () {
varInfo.clear(); varInfo.clear();
nrRegsHere.clear(); nrRegsHere.clear();
nrRegs.clear(); nrRegs.clear();
@ -797,8 +797,8 @@ void ExecutionNode::VarOverview::clear () {
totalNrRegs = 0; totalNrRegs = 0;
} }
ExecutionNode::VarOverview* ExecutionNode::VarOverview::clone (ExecutionPlan* otherPlan, ExecutionPlan* plan) { ExecutionNode::RegisterPlan* ExecutionNode::RegisterPlan::clone (ExecutionPlan* otherPlan, ExecutionPlan* plan) {
VarOverview* other = new VarOverview(); std::unique_ptr<RegisterPlan> other(new RegisterPlan());
other->nrRegsHere = nrRegsHere; other->nrRegsHere = nrRegsHere;
other->nrRegs = nrRegs; other->nrRegs = nrRegs;
@ -807,17 +807,13 @@ ExecutionNode::VarOverview* ExecutionNode::VarOverview::clone (ExecutionPlan* ot
other->varInfo = varInfo; other->varInfo = varInfo;
/* we don't need these. // No need to clone subQueryNodes because this was only used during
for (auto en: subQueryNodes) { // the buildup.
auto otherId = en->id();
auto otherEN = otherPlan->getNodeById(otherId); return other.release();
other->subQueryNodes.push_back(otherEN);
}
*/
return other;
} }
void ExecutionNode::VarOverview::after (ExecutionNode *en) { void ExecutionNode::RegisterPlan::after (ExecutionNode *en) {
switch (en->getType()) { switch (en->getType()) {
case ExecutionNode::ENUMERATE_COLLECTION: case ExecutionNode::ENUMERATE_COLLECTION:
case ExecutionNode::INDEX_RANGE: { case ExecutionNode::INDEX_RANGE: {
@ -968,7 +964,7 @@ void ExecutionNode::VarOverview::after (ExecutionNode *en) {
} }
en->_depth = depth; en->_depth = depth;
en->_varOverview = *me; en->_registerPlan = *me;
// Now find out which registers ought to be erased after this node: // Now find out which registers ought to be erased after this node:
if (en->getType() != ExecutionNode::RETURN) { if (en->getType() != ExecutionNode::RETURN) {

View File

@ -513,7 +513,7 @@ namespace triagens {
} }
}; };
struct VarOverview : public WalkerWorker<ExecutionNode> { struct RegisterPlan : public WalkerWorker<ExecutionNode> {
// The following are collected for global usage in the ExecutionBlock, // The following are collected for global usage in the ExecutionBlock,
// although they are stored here in the node: // although they are stored here in the node:
@ -536,10 +536,14 @@ namespace triagens {
unsigned int depth; unsigned int depth;
unsigned int totalNrRegs; unsigned int totalNrRegs;
// This is used to tell all nodes and share a pointer to ourselves private:
shared_ptr<VarOverview>* me;
VarOverview () // This is used to tell all nodes and share a pointer to ourselves
shared_ptr<RegisterPlan>* me;
public:
RegisterPlan ()
: depth(0), totalNrRegs(0), me(nullptr) { : depth(0), totalNrRegs(0), me(nullptr) {
nrRegsHere.push_back(0); nrRegsHere.push_back(0);
nrRegs.push_back(0); nrRegs.push_back(0);
@ -547,13 +551,13 @@ namespace triagens {
void clear (); void clear ();
void setSharedPtr (shared_ptr<VarOverview>* shared) { void setSharedPtr (shared_ptr<RegisterPlan>* shared) {
me = shared; me = shared;
} }
// Copy constructor used for a subquery: // Copy constructor used for a subquery:
VarOverview (VarOverview const& v, unsigned int newdepth); RegisterPlan (RegisterPlan const& v, unsigned int newdepth);
~VarOverview () {}; ~RegisterPlan () {};
virtual bool enterSubquery (ExecutionNode*, virtual bool enterSubquery (ExecutionNode*,
ExecutionNode*) { ExecutionNode*) {
@ -562,7 +566,7 @@ namespace triagens {
virtual void after (ExecutionNode *eb); virtual void after (ExecutionNode *eb);
VarOverview* clone(ExecutionPlan* otherPlan, ExecutionPlan* plan); RegisterPlan* clone(ExecutionPlan* otherPlan, ExecutionPlan* plan);
}; };
@ -573,12 +577,12 @@ namespace triagens {
void planRegisters (ExecutionNode* super = nullptr); void planRegisters (ExecutionNode* super = nullptr);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief get varOverview /// @brief get RegisterPlan
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
VarOverview const* getVarOverview () const { RegisterPlan const* getRegisterPlan () const {
TRI_ASSERT(_varOverview.get() != nullptr); TRI_ASSERT(_registerPlan.get() != nullptr);
return _varOverview.get(); return _registerPlan.get();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -702,7 +706,7 @@ namespace triagens {
/// @brief info about variables, filled in by planRegisters /// @brief info about variables, filled in by planRegisters
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VarOverview> _varOverview; std::shared_ptr<RegisterPlan> _registerPlan;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief depth of the current frame, will be filled in by planRegisters /// @brief depth of the current frame, will be filled in by planRegisters

View File

@ -280,7 +280,7 @@ static int SetupExampleObject (v8::Handle<v8::Object> const example,
static TRI_index_operator_t* SetupConditionsSkiplist (TRI_index_t* idx, static TRI_index_operator_t* SetupConditionsSkiplist (TRI_index_t* idx,
TRI_shaper_t* shaper, TRI_shaper_t* shaper,
v8::Handle<v8::Object> conditions) { v8::Handle<v8::Object> conditions) {
TRI_index_operator_t* lastOperator = 0; TRI_index_operator_t* lastOperator = nullptr;
size_t numEq = 0; size_t numEq = 0;
size_t lastNonEq = 0; size_t lastNonEq = 0;
@ -449,7 +449,7 @@ static TRI_index_operator_t* SetupConditionsSkiplist (TRI_index_t* idx,
MEM_ERROR: MEM_ERROR:
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, parameters); TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, parameters);
if (lastOperator == nullptr) { if (lastOperator != nullptr) {
TRI_FreeIndexOperator(lastOperator); TRI_FreeIndexOperator(lastOperator);
} }

View File

@ -411,8 +411,8 @@
this.collection.each(function(model) { this.collection.each(function(model) {
self.customQueries.push({ self.customQueries.push({
name: model.attributes.name, name: model.get("name"),
value: model.attributes.value value: model.get("value")
}); });
}); });
}, },

View File

@ -4589,7 +4589,6 @@ function TRAVERSAL_VISITOR (config, result, vertex, path) {
function TRAVERSAL_NEIGHBOR_VISITOR (config, result, vertex, path) { function TRAVERSAL_NEIGHBOR_VISITOR (config, result, vertex, path) {
"use strict"; "use strict";
result.push(CLONE({ vertex: vertex, path: path, startVertex : config.startVertex })); result.push(CLONE({ vertex: vertex, path: path, startVertex : config.startVertex }));
} }
@ -4653,10 +4652,23 @@ function TRAVERSAL_EDGE_EXAMPLE_FILTER (config, vertex, edge, path) {
function TRAVERSAL_VERTEX_FILTER (config, vertex, path) { function TRAVERSAL_VERTEX_FILTER (config, vertex, path) {
"use strict"; "use strict";
if (config.filterVertexExamples && !MATCHES(vertex, config.filterVertexExamples)) {
if (! MATCHES(vertex, config.filterVertexExamples)) { if (config.filterVertexCollections
&& config.vertexFilterMethod.indexOf("exclude") === -1
&& config.filterVertexCollections.indexOf(vertex._id.split("/")[0]) === -1
) {
if (config.vertexFilterMethod.indexOf("prune") === -1) {
return ["exclude"];
}
return ["prune", "exclude"];
}
return config.vertexFilterMethod; return config.vertexFilterMethod;
} }
if (config.filterVertexCollections
&& config.filterVertexCollections.indexOf(vertex._id.split("/")[0]) === -1
){
return ["exclude"];
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -4789,6 +4801,11 @@ function TRAVERSAL_FUNC (func,
config.vertexFilterMethod = params.vertexFilterMethod || ["prune", "exclude"]; config.vertexFilterMethod = params.vertexFilterMethod || ["prune", "exclude"];
} }
} }
if (params.filterVertexCollections) {
config.filter = config.filter || TRAVERSAL_VERTEX_FILTER;
config.vertexFilterMethod = config.vertexFilterMethod || ["prune", "exclude"];
config.filterVertexCollections = params.filterVertexCollections;
}
if (params._sort) { if (params._sort) {
config.sort = function (l, r) { return l._key < r._key ? -1 : 1; }; config.sort = function (l, r) { return l._key < r._key ? -1 : 1; };
@ -6020,8 +6037,8 @@ function GRAPH_NEIGHBORS (vertexCollection,
/// * *edgeCollectionRestriction* : One or multiple edge /// * *edgeCollectionRestriction* : One or multiple edge
/// collection names. Only edges from these collections will be considered for the path. /// collection names. Only edges from these collections will be considered for the path.
/// * *vertexCollectionRestriction* : One or multiple vertex /// * *vertexCollectionRestriction* : One or multiple vertex
/// collection names. Only vertices from these collections will be considered as /// collection names. Only vertices from these collections will be contained in the
/// neighbor. /// result. This does not effect vertices on the path.
/// * *minDepth* : Defines the minimal /// * *minDepth* : Defines the minimal
/// depth a path to a neighbor must have to be returned (default is 1). /// depth a path to a neighbor must have to be returned (default is 1).
/// * *maxDepth* : Defines the maximal /// * *maxDepth* : Defines the maximal
@ -6064,22 +6081,13 @@ function GENERAL_GRAPH_NEIGHBORS (graphName,
} }
options.fromVertexExample = vertexExample; options.fromVertexExample = vertexExample;
if (! options.direction) { if (! options.hasOwnProperty("direction")) {
options.direction = 'any'; options.direction = 'any';
} }
if (options.vertexCollectionRestriction) { if (options.hasOwnProperty("neighborExamples") && typeof options.neighborExamples === "string") {
if (options.direction === "inbound") {
options.endVertexCollectionRestriction = options.vertexCollectionRestriction;
} else {
options.startVertexCollectionRestriction = options.vertexCollectionRestriction;
}
}
if (options.neighborExamples) {
if (typeof options.neighborExamples === "string") {
options.neighborExamples = {_id : options.neighborExamples}; options.neighborExamples = {_id : options.neighborExamples};
} }
}
var neighbors = [], var neighbors = [],
params = TRAVERSAL_PARAMS(), params = TRAVERSAL_PARAMS(),
factory = TRAVERSAL.generalGraphDatasourceFactory(graphName); factory = TRAVERSAL.generalGraphDatasourceFactory(graphName);
@ -6094,6 +6102,9 @@ function GENERAL_GRAPH_NEIGHBORS (graphName,
if (options.edgeCollectionRestriction) { if (options.edgeCollectionRestriction) {
params.edgeCollectionRestriction = options.edgeCollectionRestriction; params.edgeCollectionRestriction = options.edgeCollectionRestriction;
} }
if (options.vertexCollectionRestriction) {
params.filterVertexCollections = options.vertexCollectionRestriction;
}
fromVertices.forEach(function (v) { fromVertices.forEach(function (v) {
var e = TRAVERSAL_FUNC("GRAPH_NEIGHBORS", var e = TRAVERSAL_FUNC("GRAPH_NEIGHBORS",
factory, factory,

View File

@ -33,6 +33,7 @@ var TRAVERSAL = require("org/arangodb/graph/traversal");
var ArangoError = require("org/arangodb").ArangoError; var ArangoError = require("org/arangodb").ArangoError;
var ShapedJson = INTERNAL.ShapedJson; var ShapedJson = INTERNAL.ShapedJson;
var isCoordinator = require("org/arangodb/cluster").isCoordinator(); var isCoordinator = require("org/arangodb/cluster").isCoordinator();
var console = require("console");
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables
@ -491,10 +492,15 @@ function FCALL_USER (name, parameters) {
} }
if (UserFunctions[prefix].hasOwnProperty(name)) { if (UserFunctions[prefix].hasOwnProperty(name)) {
try {
var result = UserFunctions[prefix][name].func.apply(null, parameters); var result = UserFunctions[prefix][name].func.apply(null, parameters);
return FIX_VALUE(result); return FIX_VALUE(result);
} }
catch (err) {
console.warn("AQL user function '%s' returned an exception. result is converted to null", name);
return null;
}
}
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, NORMALIZE_FNAME(name)); THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_NOT_FOUND, NORMALIZE_FNAME(name));
} }

View File

@ -41,6 +41,7 @@ var assertQueryError = helper.assertQueryError;
function ahuacatlQueryGeneralEdgesTestSuite() { function ahuacatlQueryGeneralEdgesTestSuite() {
var gN = "bla3";
var v1 = "UnitTestsAhuacatlVertex1"; var v1 = "UnitTestsAhuacatlVertex1";
var v2 = "UnitTestsAhuacatlVertex2"; var v2 = "UnitTestsAhuacatlVertex2";
var v3 = "UnitTestsAhuacatlVertex3"; var v3 = "UnitTestsAhuacatlVertex3";
@ -49,6 +50,13 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
var e2 = "UnitTestsAhuacatlEdge2"; var e2 = "UnitTestsAhuacatlEdge2";
var or = "UnitTestsAhuacatlOrphan"; var or = "UnitTestsAhuacatlOrphan";
var AQL_VERTICES = "FOR e IN GRAPH_VERTICES(@name, @example, @options) SORT e._id RETURN e";
var AQL_EDGES = "FOR e IN GRAPH_EDGES(@name, @example, @options) SORT e.what RETURN e.what";
var AQL_NEIGHBORS = "FOR e IN GRAPH_NEIGHBORS(@name, @example, @options) SORT e.vertex._id, e.path.edges[0].what RETURN e";
var startExample = [{hugo : true}, {heinz : 1}];
var vertexExample = {_key: "v1"};
return { return {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -128,96 +136,801 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief checks GRAPH_EDGES() and GRAPH_NEIGHBOURS() and GRAPH_VERTICES() /// @brief checks GRAPH_VERTICES()
////////////////////////////////////////////////////////////////////////////////
testVertices: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {direction : 'any'}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual[0]._id, v1 + '/v1');
},
testVerticesRestricted: function() {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'any',
vertexCollectionRestriction: or
}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0]._id, 'UnitTestsAhuacatlOrphan/orphan');
},
testVerticesExample: function () {
var bindVars = {
name: gN,
example: startExample,
options: {direction : 'any'}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 4);
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex1/v1');
assertEqual(actual[1]._id, 'UnitTestsAhuacatlVertex1/v2');
assertEqual(actual[2]._id, 'UnitTestsAhuacatlVertex2/v3');
assertEqual(actual[3]._id, 'UnitTestsAhuacatlVertex4/v8');
},
testVerticesWithInboundEdges: function () {
var bindVars = {
name: gN,
example: v3 + "/v5",
options: {direction : 'inbound'}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex3/v5');
},
testVerticesWithInboundEdgesHasNoInboundEdges: function () {
var bindVars = {
name: gN,
example: v2 + "/v3",
options: {direction : 'inbound'}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 0);
},
testVerticesWithInboundEdgesAndExample: function () {
var bindVars = {
name: gN,
example: startExample,
options: {direction : 'inbound'}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 3);
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex1/v1');
assertEqual(actual[1]._id, 'UnitTestsAhuacatlVertex1/v2');
assertEqual(actual[2]._id, 'UnitTestsAhuacatlVertex4/v8');
},
testVerticesWithInboundEdgesRestrictedHasNoInbound: function() {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'inbound',
vertexCollectionRestriction: v2
}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 0);
},
testVerticesWithInboundEdgesRestrictedHasInbound: function() {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'inbound',
vertexCollectionRestriction: v3
}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 2);
assertEqual(actual[0]._id, v3 + '/v5');
assertEqual(actual[1]._id, v3 + '/v6');
},
testVerticesWithOutboundEdgesRestrictedHasOutbound: function() {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'outbound',
vertexCollectionRestriction: v2
}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 2);
assertEqual(actual[0]._id, v2 + '/v3');
assertEqual(actual[1]._id, v2 + '/v4');
},
testVerticesWithOutboundEdgesRestrictedHasNoOutbound: function() {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'outbound',
vertexCollectionRestriction: v3
}
};
var actual = getRawQueryResults(AQL_VERTICES, bindVars);
assertEqual(actual.length, 0);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief checks GRAPH_EDGES()
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Section any direction
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testEdgesAny: function () { testEdgesAny: function () {
var bindVars = {
var actual; name: gN,
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', '" + v1 + "/v1', {direction : 'any'}) RETURN e"); example: v1 + "/v1",
assertEqual(actual[0]._id, v1 + '/v1'); options: {direction : 'any'}
};
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', {}, {direction : 'any', vertexCollectionRestriction : 'UnitTestsAhuacatlOrphan'}) RETURN e"); var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual[0]._id, 'UnitTestsAhuacatlOrphan/orphan');
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'any'}) SORT e.what RETURN e.what");
assertEqual(actual, [ "v1->v2", "v1->v5", "v2->v1" ]); assertEqual(actual, [ "v1->v2", "v1->v5", "v2->v1" ]);
},
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'any' , edgeCollectionRestriction: ['UnitTestsAhuacatlEdge1']}) " + testEdgesAnyRestricted: function () {
"SORT e.what RETURN e.what"); var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'any',
edgeCollectionRestriction: [e1]
}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual, [ "v1->v2", "v2->v1" ]); assertEqual(actual, [ "v1->v2", "v2->v1" ]);
},
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', [{hugo : true}, {heinz : 1}], {direction : 'any'}) " + testEdgesAnyStartExample: function () {
"SORT e.what RETURN e.what"); var bindVars = {
assertEqual(actual, [ "v1->v2", name: gN,
example: startExample,
options: {direction : 'any'}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual, [
"v1->v2",
"v1->v5", "v1->v5",
"v2->v1", "v2->v1",
"v2->v5", "v2->v5",
"v3->v5", "v3->v5",
"v3->v6", "v3->v6",
"v3->v8" ]); "v3->v8"
]);
},
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', [{hugo : true}, {heinz : 1}], {direction : 'any'}) SORT e._id RETURN e"); testEdgesAnyStartExampleEdgeExample: function () {
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex1/v1'); var bindVars = {
assertEqual(actual[1]._id, 'UnitTestsAhuacatlVertex1/v2'); name: gN,
assertEqual(actual[2]._id, 'UnitTestsAhuacatlVertex2/v3'); example: v1 + "/v1",
assertEqual(actual[3]._id, 'UnitTestsAhuacatlVertex4/v8'); options: {
direction : 'any',
edgeExamples: [{what: 'v2->v1'}]
}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0], "v2->v1");
},
testEdgesInbound: function() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'any' , edgeExamples : [{'what' : 'v2->v1'}]}) SORT e.what RETURN e.what"); var bindVars = {
name: gN,
example: v1 + "/v1",
options: {direction : 'inbound'}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual, [ "v2->v1"]); assertEqual(actual, [ "v2->v1"]);
},
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'any' , edgeExamples : [{'what' : 'v2->v1'}]}) SORT e.what RETURN e"); testEdgesInboundStartExample: function() {
var bindVars = {
name: gN,
example: startExample,
options: {direction : 'inbound'}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 3);
assertEqual(actual[0], "v1->v2");
assertEqual(actual[1], "v2->v1");
assertEqual(actual[2], "v3->v8");
},
testEdgesInboundStartExampleRestricted: function() {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound',
edgeCollectionRestriction: [e2]
}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0], "v3->v8");
},
testEdgesInboundStartExampleEdgeExample: function() {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound',
edgeExamples: [{'what' : 'v3->v8'}]
}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0], "v3->v8");
},
testEdgesOutbound: function() {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {direction : 'outbound'}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual[0], "v1->v2");
assertEqual(actual[1], "v1->v5");
},
testEdgesOutboundStartExample: function() {
var bindVars = {
name: gN,
example: startExample,
options: {direction : 'outbound'}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 7);
assertEqual(actual[0], "v1->v2");
assertEqual(actual[1], "v1->v5");
assertEqual(actual[2], "v2->v1");
assertEqual(actual[3], "v2->v5");
assertEqual(actual[4], "v3->v5");
assertEqual(actual[5], "v3->v6");
assertEqual(actual[6], "v3->v8");
},
testEdgesOutboundStartExampleRestricted: function() {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'outbound',
edgeCollectionRestriction: [e2]
}
};
var actual = getRawQueryResults(AQL_EDGES, bindVars);
assertEqual(actual.length, 5);
assertEqual(actual[0], "v1->v5");
assertEqual(actual[1], "v2->v5");
assertEqual(actual[2], "v3->v5");
assertEqual(actual[3], "v3->v6");
assertEqual(actual[4], "v3->v8");
},
////////////////////////////////////////////////////////////////////////////////
/// Test Neighbors
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Any direction
////////////////////////////////////////////////////////////////////////////////
testNeighborsAny: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'any'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 3);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2");
assertEqual(actual[1].path.edges[0].what, "v2->v1");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v2");
assertEqual(actual[2].path.edges[0].what, "v1->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
},
testNeighborsAnyEdgeExample: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'any',
edgeExamples : [{'what' : 'v2->v1'}]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v2->v1"); assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2"); assertEqual(actual[0].vertex._key, "v2");
}, },
////////////////////////////////////////////////////////////////////////////////
/// @brief checks EDGES()
////////////////////////////////////////////////////////////////////////////////
testEdgesIn: function () { testNeighborsAnyStartExample: function () {
var actual; var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'any'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 10);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v2->v1");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v1");
assertEqual(actual[2].path.edges[0].what, "v1->v2");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v2");
assertEqual(actual[3].path.edges[0].what, "v2->v1");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v2");
assertEqual(actual[4].path.edges[0].what, "v3->v8");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v3");
assertEqual(actual[5].path.edges[0].what, "v1->v5");
assertEqual(actual[5].path.edges.length, 1);
assertEqual(actual[5].vertex._key, "v5");
assertEqual(actual[6].path.edges[0].what, "v2->v5");
assertEqual(actual[6].path.edges.length, 1);
assertEqual(actual[6].vertex._key, "v5");
assertEqual(actual[7].path.edges[0].what, "v3->v5");
assertEqual(actual[7].path.edges.length, 1);
assertEqual(actual[7].vertex._key, "v5");
assertEqual(actual[8].path.edges[0].what, "v3->v6");
assertEqual(actual[8].path.edges.length, 1);
assertEqual(actual[8].vertex._key, "v6");
assertEqual(actual[9].path.edges[0].what, "v3->v8");
assertEqual(actual[9].path.edges.length, 1);
assertEqual(actual[9].vertex._key, "v8");
},
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', {direction : 'inbound'}) SORT e.what RETURN e.what"); testNeighborsAnyVertexExample: function () {
assertEqual(actual, [ "v1->v5", "v2->v5", "v3->v5"]); var bindVars = {
name: gN,
example: {},
options: {
direction : 'any',
neighborExamples: vertexExample
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 3);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v1->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v1");
assertEqual(actual[2].path.edges[0].what, "v2->v1");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v1");
},
testNeighborsAnyStartExampleRestrictEdges: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'any',
edgeCollectionRestriction: e2
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 6);
assertEqual(actual[0].path.edges[0].what, "v3->v8");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v3");
assertEqual(actual[1].path.edges[0].what, "v1->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v5");
assertEqual(actual[2].path.edges[0].what, "v2->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v3->v5");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v5");
assertEqual(actual[4].path.edges[0].what, "v3->v6");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v6");
assertEqual(actual[5].path.edges[0].what, "v3->v8");
assertEqual(actual[5].path.edges.length, 1);
assertEqual(actual[5].vertex._key, "v8");
},
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', 'UnitTestsAhuacatlVertex3/v5', {direction : 'inbound'}) SORT e._id RETURN e"); testNeighborsAnyStartExampleRestrictVertices: function () {
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex3/v5'); var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'any',
vertexCollectionRestriction: [v1, v3]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 8);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v2->v1");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v1");
assertEqual(actual[2].path.edges[0].what, "v1->v2");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v2");
assertEqual(actual[3].path.edges[0].what, "v2->v1");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v2");
assertEqual(actual[4].path.edges[0].what, "v1->v5");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v5");
assertEqual(actual[5].path.edges[0].what, "v2->v5");
assertEqual(actual[5].path.edges.length, 1);
assertEqual(actual[5].vertex._key, "v5");
assertEqual(actual[6].path.edges[0].what, "v3->v5");
assertEqual(actual[6].path.edges.length, 1);
assertEqual(actual[6].vertex._key, "v5");
assertEqual(actual[7].path.edges[0].what, "v3->v6");
assertEqual(actual[7].path.edges.length, 1);
assertEqual(actual[7].vertex._key, "v6");
},
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', [{hugo : true}, {heinz : 1}], {direction : 'inbound'}) SORT e._id RETURN e"); testNeighborsAnyStartExampleRestrictEdgesAndVertices: function () {
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex1/v1'); var bindVars = {
assertEqual(actual[1]._id, 'UnitTestsAhuacatlVertex1/v2'); name: gN,
assertEqual(actual[2]._id, 'UnitTestsAhuacatlVertex4/v8'); example: startExample,
assertTrue(actual.length === 3); options: {
direction : 'any',
vertexCollectionRestriction: [v1, v3],
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', {direction : 'inbound' ,edgeCollectionRestriction: 'UnitTestsAhuacatlEdge2'}) SORT e.what RETURN e.what"); edgeCollectionRestriction: e2
assertEqual(actual, [ "v1->v5", "v2->v5", "v3->v5"]); }
};
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', {direction : 'inbound' , edgeExamples : [{'what' : 'v2->v5'}]}) SORT e.what RETURN e.what"); var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual, [ "v2->v5" ]); assertEqual(actual.length, 4);
assertEqual(actual[0].path.edges[0].what, "v1->v5");
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex3/v5', {direction : 'inbound' , edgeExamples : [{'what' : 'v2->v5'}]}) SORT e.what RETURN e"); assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].path.edges[0].what, "v2->v5"); assertEqual(actual[0].vertex._key, "v5");
assertEqual(actual[0].vertex._key, "v2"); assertEqual(actual[1].path.edges[0].what, "v2->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v5");
assertEqual(actual[2].path.edges[0].what, "v3->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v3->v6");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v6");
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief checks EDGES() /// direction outbound
////////////////////////////////////////////////////////////////////////////////
testNeighborsOutbound: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'outbound'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 2);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2");
assertEqual(actual[1].path.edges[0].what, "v1->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v5");
},
testNeighborsOutboundEdgeExample: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'outbound',
edgeExamples : [{'what' : 'v1->v2'}, {'what' : 'v2->v1'}]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2");
},
testNeighborsOutboundStartExample: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'outbound'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 7);
assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v1->v2");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v2");
assertEqual(actual[2].path.edges[0].what, "v1->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v2->v5");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v5");
assertEqual(actual[4].path.edges[0].what, "v3->v5");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v5");
assertEqual(actual[5].path.edges[0].what, "v3->v6");
assertEqual(actual[5].path.edges.length, 1);
assertEqual(actual[5].vertex._key, "v6");
assertEqual(actual[6].path.edges[0].what, "v3->v8");
assertEqual(actual[6].path.edges.length, 1);
assertEqual(actual[6].vertex._key, "v8");
},
testNeighborsOutboundVertexExample: function () {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'outbound',
neighborExamples: vertexExample
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
},
testNeighborsOutboundStartExampleRestrictEdges: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'outbound',
edgeCollectionRestriction: e2
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 5);
assertEqual(actual[0].path.edges[0].what, "v1->v5");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v5");
assertEqual(actual[1].path.edges[0].what, "v2->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v5");
assertEqual(actual[2].path.edges[0].what, "v3->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v3->v6");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v6");
assertEqual(actual[4].path.edges[0].what, "v3->v8");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v8");
},
testNeighborsOutboundStartExampleRestrictVertices: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'outbound',
vertexCollectionRestriction: [v1, v3]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 6);
assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v1->v2");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v2");
assertEqual(actual[2].path.edges[0].what, "v1->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v2->v5");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v5");
assertEqual(actual[4].path.edges[0].what, "v3->v5");
assertEqual(actual[4].path.edges.length, 1);
assertEqual(actual[4].vertex._key, "v5");
assertEqual(actual[5].path.edges[0].what, "v3->v6");
assertEqual(actual[5].path.edges.length, 1);
assertEqual(actual[5].vertex._key, "v6");
},
testNeighborsOutboundStartExampleRestrictEdgesAndVertices: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'outbound',
vertexCollectionRestriction: [v1, v3],
edgeCollectionRestriction: e2
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 4);
assertEqual(actual[0].path.edges[0].what, "v1->v5");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v5");
assertEqual(actual[1].path.edges[0].what, "v2->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v5");
assertEqual(actual[2].path.edges[0].what, "v3->v5");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v5");
assertEqual(actual[3].path.edges[0].what, "v3->v6");
assertEqual(actual[3].path.edges.length, 1);
assertEqual(actual[3].vertex._key, "v6");
},
////////////////////////////////////////////////////////////////////////////////
/// inbound direction
////////////////////////////////////////////////////////////////////////////////
testNeighborsInbound: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'inbound'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2");
},
testNeighborsInboundEdgeExample: function () {
var bindVars = {
name: gN,
example: v1 + "/v1",
options: {
direction : 'inbound',
edgeExamples : [{'what' : 'v2->v1'}]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v2->v1");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v2");
},
testNeighborsInboundStartExample: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound'
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 3);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v2->v1");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v2");
assertEqual(actual[2].path.edges[0].what, "v3->v8");
assertEqual(actual[2].path.edges.length, 1);
assertEqual(actual[2].vertex._key, "v3");
},
testNeighborsInboundNeighborExample: function () {
var bindVars = {
name: gN,
example: {},
options: {
direction : 'inbound',
neighborExamples: vertexExample
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 2);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v1->v5");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v1");
},
testNeighborsInboundStartExampleRestrictEdges: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound',
edgeCollectionRestriction: e2
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 1);
assertEqual(actual[0].path.edges[0].what, "v3->v8");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v3");
},
testNeighborsInboundStartExampleRestrictVertices: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound',
vertexCollectionRestriction: [v1, v3]
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 2);
assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].path.edges.length, 1);
assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].path.edges[0].what, "v2->v1");
assertEqual(actual[1].path.edges.length, 1);
assertEqual(actual[1].vertex._key, "v2");
},
testNeighborsInboundStartExampleRestrictEdgesAndVertices: function () {
var bindVars = {
name: gN,
example: startExample,
options: {
direction : 'inbound',
vertexCollectionRestriction: [v1, v3],
edgeCollectionRestriction: e2
}
};
var actual = getRawQueryResults(AQL_NEIGHBORS, bindVars);
assertEqual(actual.length, 0);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief checks EDGES() OLD
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testEdgesOut: function () { testEdgesOut: function () {
var actual; var actual;
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound'}) SORT e.what RETURN e.what");
assertEqual(actual, [ "v1->v2", "v1->v5"]);
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound' ,edgeCollectionRestriction: 'UnitTestsAhuacatlEdge2'}) SORT e.what RETURN e.what");
assertEqual(actual, [ "v1->v5"]);
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound' ,edgeExamples : [{'what' : 'v2->v5'}]}) SORT e.what RETURN e.what");
assertEqual(actual, []);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound' ,minDepth : 1, maxDepth : 3}) SORT e.vertex._key RETURN e"); actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound' ,minDepth : 1, maxDepth : 3}) SORT e.vertex._key RETURN e");
assertEqual(actual[0].vertex._key, "v1"); assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].vertex._key, "v2"); assertEqual(actual[1].vertex._key, "v2");
@ -228,13 +941,6 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
assertEqual(actual[0].vertex._key, "v1"); assertEqual(actual[0].vertex._key, "v1");
assertEqual(actual[1].vertex._key, "v2"); assertEqual(actual[1].vertex._key, "v2");
actual = getRawQueryResults("FOR e IN GRAPH_VERTICES('bla3', [{hugo : true}, {heinz : 1}], {direction : 'outbound'}) SORT e._id RETURN e");
assertEqual(actual[0]._id, 'UnitTestsAhuacatlVertex1/v1');
assertEqual(actual[1]._id, 'UnitTestsAhuacatlVertex1/v2');
assertEqual(actual[2]._id, 'UnitTestsAhuacatlVertex2/v3');
assertTrue(actual.length === 3);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound'}) SORT e.what RETURN e"); actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', {direction : 'outbound'}) SORT e.what RETURN e");
assertEqual(actual[0].path.edges[0].what, "v1->v2"); assertEqual(actual[0].path.edges[0].what, "v1->v2");
assertEqual(actual[0].vertex._key, "v2"); assertEqual(actual[0].vertex._key, "v2");
@ -344,7 +1050,7 @@ function ahuacatlQueryGeneralCommonTestSuite() {
/// @brief checks GRAPH_COMMON_NEIGHBORS() and GRAPH_COMMON_PROPERTIES() /// @brief checks GRAPH_COMMON_NEIGHBORS() and GRAPH_COMMON_PROPERTIES()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testEdgesAny: function () { testCommonNeighbors: function () {
var actual = getQueryResults("FOR e IN GRAPH_COMMON_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v3' , 'UnitTestsAhuacatlVertex2/v6', {direction : 'any'}) SORT ATTRIBUTES(e)[0] RETURN e"); var actual = getQueryResults("FOR e IN GRAPH_COMMON_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v3' , 'UnitTestsAhuacatlVertex2/v6', {direction : 'any'}) SORT ATTRIBUTES(e)[0] RETURN e");
assertEqual(actual[0]["UnitTestsAhuacatlVertex1/v3"]["UnitTestsAhuacatlVertex2/v6"][0]._id, "UnitTestsAhuacatlVertex1/v2"); assertEqual(actual[0]["UnitTestsAhuacatlVertex1/v3"]["UnitTestsAhuacatlVertex2/v6"][0]._id, "UnitTestsAhuacatlVertex1/v2");
@ -396,23 +1102,27 @@ function ahuacatlQueryGeneralCommonTestSuite() {
/// @brief checks GRAPH_COMMON_NEIGHBORS() /// @brief checks GRAPH_COMMON_NEIGHBORS()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testCommonNeighborsMixedOptions: function () { testCommonNeighborsMixedOptionsDistinctFilters: function () {
var actual = getQueryResults("FOR e IN GRAPH_COMMON_NEIGHBORS('bla3', {} , {}, " + var actual = getQueryResults("FOR e IN GRAPH_COMMON_NEIGHBORS('bla3', {} , {}, " +
"{direction : 'outbound', vertexCollectionRestriction : 'UnitTestsAhuacatlVertex1'}, " + "{direction : 'outbound', vertexCollectionRestriction : 'UnitTestsAhuacatlVertex1'}, " +
"{direction : 'inbound', minDepth : 1, maxDepth : 2, vertexCollectionRestriction : 'UnitTestsAhuacatlVertex2'}) SORT TO_STRING(e) RETURN e"); "{direction : 'inbound', minDepth : 1, maxDepth : 2, vertexCollectionRestriction : 'UnitTestsAhuacatlVertex2'}) SORT TO_STRING(e) RETURN e");
assertEqual(Object.keys(actual[0])[0], "UnitTestsAhuacatlVertex1/v2"); assertEqual(actual.length, 0);
assertEqual(Object.keys(actual[0][Object.keys(actual[0])[0]]).sort(), ["UnitTestsAhuacatlVertex2/v5", "UnitTestsAhuacatlVertex2/v7", "UnitTestsAhuacatlVertex2/v8"]); },
assertEqual(actual[0][Object.keys(actual[0])[0]]["UnitTestsAhuacatlVertex2/v5"].length, 1); testCommonNeighborsMixedOptionsFilterBasedOnOneCollectionOnly: function () {
assertEqual(actual[0][Object.keys(actual[0])[0]]["UnitTestsAhuacatlVertex2/v8"].length, 1); var actual = getQueryResults("FOR e IN GRAPH_COMMON_NEIGHBORS('bla3', {} , {}, " +
assertEqual(actual[0][Object.keys(actual[0])[0]]["UnitTestsAhuacatlVertex2/v7"].length, 2); "{direction : 'outbound', vertexCollectionRestriction : 'UnitTestsAhuacatlVertex2'}, " +
"{direction : 'inbound', minDepth : 1, maxDepth : 2, vertexCollectionRestriction : 'UnitTestsAhuacatlVertex2'}) SORT TO_STRING(e) RETURN e");
assertEqual(Object.keys(actual[1])[0], "UnitTestsAhuacatlVertex1/v1"); assertEqual(Object.keys(actual[0])[0], "UnitTestsAhuacatlVertex1/v3");
assertEqual(Object.keys(actual[1][Object.keys(actual[1])[0]]).sort(), ["UnitTestsAhuacatlVertex2/v5", "UnitTestsAhuacatlVertex2/v6", "UnitTestsAhuacatlVertex2/v7", "UnitTestsAhuacatlVertex2/v8"]); assertEqual(Object.keys(actual[0][Object.keys(actual[0])[0]]).sort(), ["UnitTestsAhuacatlVertex1/v1", "UnitTestsAhuacatlVertex1/v2"]);
assertEqual(actual[0][Object.keys(actual[0])[0]]["UnitTestsAhuacatlVertex1/v1"].length, 1);
assertEqual(actual[0][Object.keys(actual[0])[0]]["UnitTestsAhuacatlVertex1/v2"].length, 1);
assertEqual(Object.keys(actual[1])[0], "UnitTestsAhuacatlVertex1/v2");
assertEqual(Object.keys(actual[1][Object.keys(actual[1])[0]]).sort(), ["UnitTestsAhuacatlVertex2/v7"]);
assertEqual(actual[1][Object.keys(actual[1])[0]]["UnitTestsAhuacatlVertex2/v6"].length, 1);
assertEqual(actual[1][Object.keys(actual[1])[0]]["UnitTestsAhuacatlVertex2/v5"].length, 1);
assertEqual(actual[1][Object.keys(actual[1])[0]]["UnitTestsAhuacatlVertex2/v8"].length, 1);
assertEqual(actual[1][Object.keys(actual[1])[0]]["UnitTestsAhuacatlVertex2/v7"].length, 1); assertEqual(actual[1][Object.keys(actual[1])[0]]["UnitTestsAhuacatlVertex2/v7"].length, 1);
}, },