mirror of https://gitee.com/bigwinds/arangodb
Fixed ALL== and NONE== tests for graph traversals. SingleServer and cluster
This commit is contained in:
parent
773e9971b7
commit
3a95244599
|
@ -60,8 +60,8 @@ AstNode* TraversalNode::EdgeConditionBuilder::getOutboundCondition() {
|
||||||
if (_containsCondition) {
|
if (_containsCondition) {
|
||||||
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_fromCondition);
|
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_fromCondition);
|
||||||
} else {
|
} else {
|
||||||
if (_tn->_globalEdgeCondition != nullptr) {
|
for (auto& it : _tn->_globalEdgeConditions) {
|
||||||
_modCondition->addMember(_tn->_globalEdgeCondition);
|
_modCondition->addMember(it);
|
||||||
}
|
}
|
||||||
TRI_ASSERT(_tn->_fromCondition != nullptr);
|
TRI_ASSERT(_tn->_fromCondition != nullptr);
|
||||||
TRI_ASSERT(_tn->_fromCondition->type == NODE_TYPE_OPERATOR_BINARY_EQ);
|
TRI_ASSERT(_tn->_fromCondition->type == NODE_TYPE_OPERATOR_BINARY_EQ);
|
||||||
|
@ -76,8 +76,8 @@ AstNode* TraversalNode::EdgeConditionBuilder::getInboundCondition() {
|
||||||
if (_containsCondition) {
|
if (_containsCondition) {
|
||||||
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_toCondition);
|
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_toCondition);
|
||||||
} else {
|
} else {
|
||||||
if (_tn->_globalEdgeCondition != nullptr) {
|
for (auto& it : _tn->_globalEdgeConditions) {
|
||||||
_modCondition->addMember(_tn->_globalEdgeCondition);
|
_modCondition->addMember(it);
|
||||||
}
|
}
|
||||||
TRI_ASSERT(_tn->_toCondition != nullptr);
|
TRI_ASSERT(_tn->_toCondition != nullptr);
|
||||||
TRI_ASSERT(_tn->_toCondition->type == NODE_TYPE_OPERATOR_BINARY_EQ);
|
TRI_ASSERT(_tn->_toCondition->type == NODE_TYPE_OPERATOR_BINARY_EQ);
|
||||||
|
@ -131,8 +131,6 @@ TraversalNode::TraversalNode(ExecutionPlan* plan, size_t id,
|
||||||
_tmpIdNode(_plan->getAst()->createNodeValueString("", 0)),
|
_tmpIdNode(_plan->getAst()->createNodeValueString("", 0)),
|
||||||
_fromCondition(nullptr),
|
_fromCondition(nullptr),
|
||||||
_toCondition(nullptr),
|
_toCondition(nullptr),
|
||||||
_globalEdgeCondition(nullptr),
|
|
||||||
_globalVertexCondition(nullptr),
|
|
||||||
_optionsBuild(false) {
|
_optionsBuild(false) {
|
||||||
TRI_ASSERT(_vocbase != nullptr);
|
TRI_ASSERT(_vocbase != nullptr);
|
||||||
TRI_ASSERT(direction != nullptr);
|
TRI_ASSERT(direction != nullptr);
|
||||||
|
@ -369,8 +367,6 @@ TraversalNode::TraversalNode(ExecutionPlan* plan,
|
||||||
_tmpIdNode(nullptr),
|
_tmpIdNode(nullptr),
|
||||||
_fromCondition(nullptr),
|
_fromCondition(nullptr),
|
||||||
_toCondition(nullptr),
|
_toCondition(nullptr),
|
||||||
_globalEdgeCondition(nullptr),
|
|
||||||
_globalVertexCondition(nullptr),
|
|
||||||
_optionsBuild(false) {
|
_optionsBuild(false) {
|
||||||
_options = std::make_unique<arangodb::traverser::TraverserOptions>(
|
_options = std::make_unique<arangodb::traverser::TraverserOptions>(
|
||||||
_plan->getAst()->query()->trx(), base);
|
_plan->getAst()->query()->trx(), base);
|
||||||
|
@ -523,12 +519,30 @@ TraversalNode::TraversalNode(ExecutionPlan* plan,
|
||||||
TRI_ASSERT(base.has("toCondition"));
|
TRI_ASSERT(base.has("toCondition"));
|
||||||
_toCondition = new AstNode(plan->getAst(), base.get("toCondition"));
|
_toCondition = new AstNode(plan->getAst(), base.get("toCondition"));
|
||||||
|
|
||||||
if (base.has("globalEdgeCondition")) {
|
if (base.has("globalEdgeConditions")) {
|
||||||
_globalEdgeCondition = new AstNode(plan->getAst(), base.get("globalEdgeCondition"));
|
TRI_json_t const* list =
|
||||||
|
JsonHelper::checkAndGetArrayValue(base.json(), "globalEdgeConditions");
|
||||||
|
size_t count = TRI_LengthVector(&list->_value._objects);
|
||||||
|
// List of edge collection names
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
Json cond(TRI_UNKNOWN_MEM_ZONE,
|
||||||
|
static_cast<TRI_json_t const*>(
|
||||||
|
TRI_AtVector(&list->_value._objects, i)));
|
||||||
|
_globalEdgeConditions.emplace_back(new AstNode(plan->getAst(), cond));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base.has("globalVertexCondition")) {
|
if (base.has("globalVertexConditions")) {
|
||||||
_globalVertexCondition = new AstNode(plan->getAst(), base.get("globalVertexCondition"));
|
TRI_json_t const* list =
|
||||||
|
JsonHelper::checkAndGetArrayValue(base.json(), "globalVertexConditions");
|
||||||
|
size_t count = TRI_LengthVector(&list->_value._objects);
|
||||||
|
// List of edge collection names
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
Json cond(TRI_UNKNOWN_MEM_ZONE,
|
||||||
|
static_cast<TRI_json_t const*>(
|
||||||
|
TRI_AtVector(&list->_value._objects, i)));
|
||||||
|
_globalVertexConditions.emplace_back(new AstNode(plan->getAst(), cond));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base.has("vertexConditions")) {
|
if (base.has("vertexConditions")) {
|
||||||
|
@ -745,14 +759,21 @@ void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes,
|
||||||
nodes.add(VPackValue("toCondition"));
|
nodes.add(VPackValue("toCondition"));
|
||||||
_toCondition->toVelocyPack(nodes, verbose);
|
_toCondition->toVelocyPack(nodes, verbose);
|
||||||
|
|
||||||
if (_globalEdgeCondition) {
|
if (!_globalEdgeConditions.empty()) {
|
||||||
nodes.add(VPackValue("globalEdgeCondition"));
|
nodes.add(VPackValue("globalEdgeConditions"));
|
||||||
_globalEdgeCondition->toVelocyPack(nodes, verbose);
|
nodes.openArray();
|
||||||
|
for (auto const& it : _globalEdgeConditions) {
|
||||||
|
it->toVelocyPack(nodes, verbose);
|
||||||
|
}
|
||||||
|
nodes.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_globalVertexCondition) {
|
if (!_globalVertexConditions.empty()) {
|
||||||
nodes.add(VPackValue("globalVertexCondition"));
|
nodes.add(VPackValue("globalVertexConditions"));
|
||||||
_globalVertexCondition->toVelocyPack(nodes, verbose);
|
nodes.openArray();
|
||||||
|
for (auto const& it : _globalVertexConditions) {
|
||||||
|
it->toVelocyPack(nodes, verbose);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_vertexConditions.empty()) {
|
if (!_vertexConditions.empty()) {
|
||||||
|
@ -840,13 +861,12 @@ ExecutionNode* TraversalNode::clone(ExecutionPlan* plan, bool withDependencies,
|
||||||
// Filter Condition Parts
|
// Filter Condition Parts
|
||||||
c->_fromCondition = _fromCondition->clone(_plan->getAst());
|
c->_fromCondition = _fromCondition->clone(_plan->getAst());
|
||||||
c->_toCondition = _toCondition->clone(_plan->getAst());
|
c->_toCondition = _toCondition->clone(_plan->getAst());
|
||||||
if (c->_globalEdgeCondition != nullptr) {
|
c->_globalEdgeConditions.insert(c->_globalEdgeConditions.end(),
|
||||||
c->_globalEdgeCondition = _globalEdgeCondition;
|
_globalEdgeConditions.begin(),
|
||||||
}
|
_globalEdgeConditions.end());
|
||||||
|
c->_globalVertexConditions.insert(c->_globalVertexConditions.end(),
|
||||||
if (c->_globalVertexCondition != nullptr) {
|
_globalVertexConditions.begin(),
|
||||||
c->_globalVertexCondition = _globalVertexCondition;
|
_globalVertexConditions.end());
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& it : _edgeConditions) {
|
for (auto const& it : _edgeConditions) {
|
||||||
c->_edgeConditions.emplace(it.first, it.second);
|
c->_edgeConditions.emplace(it.first, it.second);
|
||||||
|
@ -952,6 +972,10 @@ void TraversalNode::prepareOptions() {
|
||||||
for (std::pair<size_t, EdgeConditionBuilder> it : _edgeConditions) {
|
for (std::pair<size_t, EdgeConditionBuilder> it : _edgeConditions) {
|
||||||
auto ins = _options->_depthLookupInfo.emplace(
|
auto ins = _options->_depthLookupInfo.emplace(
|
||||||
it.first, std::vector<traverser::TraverserOptions::LookupInfo>());
|
it.first, std::vector<traverser::TraverserOptions::LookupInfo>());
|
||||||
|
// We probably have to adopt minDepth. We cannot fulfill a condition of larger depth anyway
|
||||||
|
if (_options->minDepth < it.first + 1) {
|
||||||
|
_options->minDepth = it.first + 1;
|
||||||
|
}
|
||||||
TRI_ASSERT(ins.second);
|
TRI_ASSERT(ins.second);
|
||||||
auto& infos = ins.first->second;
|
auto& infos = ins.first->second;
|
||||||
infos.reserve(numEdgeColls);
|
infos.reserve(numEdgeColls);
|
||||||
|
@ -975,7 +999,6 @@ void TraversalNode::prepareOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
info.expression = new Expression(ast, info.indexCondition->clone(ast));
|
info.expression = new Expression(ast, info.indexCondition->clone(ast));
|
||||||
#warning hard-coded nrItems.
|
|
||||||
res = trx->getBestIndexHandleForFilterCondition(
|
res = trx->getBestIndexHandleForFilterCondition(
|
||||||
_edgeColls[i]->getName(), info.indexCondition, _tmpObjVariable, 1000,
|
_edgeColls[i]->getName(), info.indexCondition, _tmpObjVariable, 1000,
|
||||||
info.idxHandles[0]);
|
info.idxHandles[0]);
|
||||||
|
@ -986,9 +1009,25 @@ void TraversalNode::prepareOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : _vertexConditions) {
|
for (auto& it : _vertexConditions) {
|
||||||
|
// We inject the base conditions as well here.
|
||||||
|
for (auto const& jt : _globalVertexConditions) {
|
||||||
|
it.second->addMember(jt);
|
||||||
|
}
|
||||||
_options->_vertexExpressions.emplace(it.first, new Expression(ast, it.second));
|
_options->_vertexExpressions.emplace(it.first, new Expression(ast, it.second));
|
||||||
|
if (_options->minDepth < it.first) {
|
||||||
|
_options->minDepth = it.first;
|
||||||
|
}
|
||||||
TRI_ASSERT(!_options->_vertexExpressions[it.first]->isV8());
|
TRI_ASSERT(!_options->_vertexExpressions[it.first]->isV8());
|
||||||
}
|
}
|
||||||
|
if (!_globalVertexConditions.empty()) {
|
||||||
|
auto cond = _plan->getAst()->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
|
||||||
|
for (auto const& it : _globalVertexConditions) {
|
||||||
|
cond->addMember(it);
|
||||||
|
}
|
||||||
|
_options->_baseVertexExpression = new Expression(ast, cond);
|
||||||
|
TRI_ASSERT(!_options->_baseVertexExpression->isV8());
|
||||||
|
|
||||||
|
}
|
||||||
_optionsBuild = true;
|
_optionsBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,9 +1073,6 @@ void TraversalNode::registerCondition(bool isConditionOnEdge,
|
||||||
auto const& it = _vertexConditions.find(conditionLevel);
|
auto const& it = _vertexConditions.find(conditionLevel);
|
||||||
if (it == _vertexConditions.end()) {
|
if (it == _vertexConditions.end()) {
|
||||||
auto cond = _plan->getAst()->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
|
auto cond = _plan->getAst()->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
|
||||||
if (_globalVertexCondition != nullptr) {
|
|
||||||
cond->addMember(_globalVertexCondition);
|
|
||||||
}
|
|
||||||
cond->addMember(condition);
|
cond->addMember(condition);
|
||||||
_vertexConditions.emplace(conditionLevel, cond);
|
_vertexConditions.emplace(conditionLevel, cond);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1049,9 +1085,9 @@ void TraversalNode::registerGlobalCondition(bool isConditionOnEdge,
|
||||||
AstNode const* condition) {
|
AstNode const* condition) {
|
||||||
Ast::getReferencedVariables(condition, _conditionVariables);
|
Ast::getReferencedVariables(condition, _conditionVariables);
|
||||||
if (isConditionOnEdge) {
|
if (isConditionOnEdge) {
|
||||||
_globalEdgeCondition = condition;
|
_globalEdgeConditions.emplace_back(condition);
|
||||||
} else {
|
} else {
|
||||||
_globalVertexCondition = condition;
|
_globalVertexConditions.emplace_back(condition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,10 +324,10 @@ class TraversalNode : public ExecutionNode {
|
||||||
|
|
||||||
/// @brief The global edge condition. Does not contain
|
/// @brief The global edge condition. Does not contain
|
||||||
/// _from and _to checks
|
/// _from and _to checks
|
||||||
AstNode const* _globalEdgeCondition;
|
std::vector<AstNode const*> _globalEdgeConditions;
|
||||||
|
|
||||||
/// @brief The global vertex condition
|
/// @brief The global vertex condition
|
||||||
AstNode const* _globalVertexCondition;
|
std::vector<AstNode const*> _globalVertexConditions;
|
||||||
|
|
||||||
/// @brief List of all depth specific conditions for edges
|
/// @brief List of all depth specific conditions for edges
|
||||||
std::unordered_map<size_t, EdgeConditionBuilder> _edgeConditions;
|
std::unordered_map<size_t, EdgeConditionBuilder> _edgeConditions;
|
||||||
|
|
|
@ -124,6 +124,7 @@ void arangodb::traverser::TraverserOptions::LookupInfo::buildEngineInfo(
|
||||||
arangodb::traverser::TraverserOptions::TraverserOptions(
|
arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
arangodb::Transaction* trx, Json const& json)
|
arangodb::Transaction* trx, Json const& json)
|
||||||
: _trx(trx),
|
: _trx(trx),
|
||||||
|
_baseVertexExpression(nullptr),
|
||||||
_tmpVar(nullptr),
|
_tmpVar(nullptr),
|
||||||
_ctx(new aql::FixedVarExpressionContext()),
|
_ctx(new aql::FixedVarExpressionContext()),
|
||||||
minDepth(1),
|
minDepth(1),
|
||||||
|
@ -165,6 +166,7 @@ arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
arangodb::traverser::TraverserOptions::TraverserOptions(
|
arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
arangodb::aql::Query* query, VPackSlice info, VPackSlice collections)
|
arangodb::aql::Query* query, VPackSlice info, VPackSlice collections)
|
||||||
: _trx(query->trx()),
|
: _trx(query->trx()),
|
||||||
|
_baseVertexExpression(nullptr),
|
||||||
_tmpVar(nullptr),
|
_tmpVar(nullptr),
|
||||||
_ctx(new aql::FixedVarExpressionContext()),
|
_ctx(new aql::FixedVarExpressionContext()),
|
||||||
minDepth(1),
|
minDepth(1),
|
||||||
|
@ -296,6 +298,18 @@ arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
TRI_ASSERT(it.second);
|
TRI_ASSERT(it.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read = info.get("baseVertexExpression");
|
||||||
|
if (!read.isNone()) {
|
||||||
|
if (!read.isObject()) {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
|
TRI_ERROR_BAD_PARAMETER,
|
||||||
|
"The options require vertexExpressions to be an object");
|
||||||
|
}
|
||||||
|
arangodb::basics::Json infoJson(TRI_UNKNOWN_MEM_ZONE,
|
||||||
|
arangodb::basics::VelocyPackHelper::velocyPackToJson(read));
|
||||||
|
_baseVertexExpression = new aql::Expression(query->ast(), infoJson);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::traverser::TraverserOptions::TraverserOptions(
|
arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
|
@ -312,6 +326,7 @@ arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
TRI_ASSERT(other._depthLookupInfo.empty());
|
TRI_ASSERT(other._depthLookupInfo.empty());
|
||||||
TRI_ASSERT(other._vertexExpressions.empty());
|
TRI_ASSERT(other._vertexExpressions.empty());
|
||||||
TRI_ASSERT(other._tmpVar == nullptr);
|
TRI_ASSERT(other._tmpVar == nullptr);
|
||||||
|
TRI_ASSERT(other._baseVertexExpression == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::traverser::TraverserOptions::~TraverserOptions() {
|
arangodb::traverser::TraverserOptions::~TraverserOptions() {
|
||||||
|
@ -320,6 +335,9 @@ arangodb::traverser::TraverserOptions::~TraverserOptions() {
|
||||||
delete pair.second;
|
delete pair.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_baseVertexExpression != nullptr) {
|
||||||
|
delete _baseVertexExpression;
|
||||||
|
}
|
||||||
if (_ctx != nullptr) {
|
if (_ctx != nullptr) {
|
||||||
delete _ctx;
|
delete _ctx;
|
||||||
}
|
}
|
||||||
|
@ -420,11 +438,18 @@ void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result
|
||||||
result.add(VPackValue("expression"));
|
result.add(VPackValue("expression"));
|
||||||
pair.second->toVelocyPack(result, true);
|
pair.second->toVelocyPack(result, true);
|
||||||
result.close();
|
result.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
result.close();
|
result.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_baseVertexExpression != nullptr) {
|
||||||
|
result.add(VPackValue("baseVertexExpression"));
|
||||||
|
result.openObject();
|
||||||
|
result.add(VPackValue("expression"));
|
||||||
|
_baseVertexExpression->toVelocyPack(result, true);
|
||||||
|
result.close();
|
||||||
|
}
|
||||||
|
|
||||||
result.add(VPackValue("tmpVar"));
|
result.add(VPackValue("tmpVar"));
|
||||||
_tmpVar->toVelocyPack(result);
|
_tmpVar->toVelocyPack(result);
|
||||||
|
|
||||||
|
@ -433,6 +458,9 @@ void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result
|
||||||
|
|
||||||
bool arangodb::traverser::TraverserOptions::vertexHasFilter(
|
bool arangodb::traverser::TraverserOptions::vertexHasFilter(
|
||||||
size_t depth) const {
|
size_t depth) const {
|
||||||
|
if (_baseVertexExpression != nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return _vertexExpressions.find(depth) != _vertexExpressions.end();
|
return _vertexExpressions.find(depth) != _vertexExpressions.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,17 +516,25 @@ bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(
|
||||||
bool arangodb::traverser::TraverserOptions::evaluateVertexExpression(
|
bool arangodb::traverser::TraverserOptions::evaluateVertexExpression(
|
||||||
arangodb::velocypack::Slice vertex, size_t depth) const {
|
arangodb::velocypack::Slice vertex, size_t depth) const {
|
||||||
bool mustDestroy = false;
|
bool mustDestroy = false;
|
||||||
|
arangodb::aql::Expression* expression = nullptr;
|
||||||
|
|
||||||
auto specific = _vertexExpressions.find(depth);
|
auto specific = _vertexExpressions.find(depth);
|
||||||
if (specific != _vertexExpressions.end()) {
|
if (specific != _vertexExpressions.end()) {
|
||||||
arangodb::aql::Expression* expression = specific->second;
|
expression = specific->second;
|
||||||
|
} else {
|
||||||
|
expression = _baseVertexExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expression == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TRI_ASSERT(!expression->isV8());
|
TRI_ASSERT(!expression->isV8());
|
||||||
expression->setVariable(_tmpVar, vertex);
|
expression->setVariable(_tmpVar, vertex);
|
||||||
aql::AqlValue res = expression->execute(_trx, _ctx, mustDestroy);
|
aql::AqlValue res = expression->execute(_trx, _ctx, mustDestroy);
|
||||||
TRI_ASSERT(res.isBoolean());
|
TRI_ASSERT(res.isBoolean());
|
||||||
expression->clearVariable(_tmpVar);
|
expression->clearVariable(_tmpVar);
|
||||||
return res.toBoolean();
|
return res.toBoolean();
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::traverser::EdgeCursor*
|
arangodb::traverser::EdgeCursor*
|
||||||
|
|
|
@ -94,6 +94,7 @@ struct TraverserOptions {
|
||||||
std::vector<LookupInfo> _baseLookupInfos;
|
std::vector<LookupInfo> _baseLookupInfos;
|
||||||
std::unordered_map<size_t, std::vector<LookupInfo>> _depthLookupInfo;
|
std::unordered_map<size_t, std::vector<LookupInfo>> _depthLookupInfo;
|
||||||
std::unordered_map<size_t, aql::Expression*> _vertexExpressions;
|
std::unordered_map<size_t, aql::Expression*> _vertexExpressions;
|
||||||
|
aql::Expression* _baseVertexExpression;
|
||||||
aql::Variable const* _tmpVar;
|
aql::Variable const* _tmpVar;
|
||||||
aql::FixedVarExpressionContext* _ctx;
|
aql::FixedVarExpressionContext* _ctx;
|
||||||
arangodb::traverser::ClusterTraverser* _traverser;
|
arangodb::traverser::ClusterTraverser* _traverser;
|
||||||
|
@ -111,6 +112,7 @@ struct TraverserOptions {
|
||||||
|
|
||||||
explicit TraverserOptions(arangodb::Transaction* trx)
|
explicit TraverserOptions(arangodb::Transaction* trx)
|
||||||
: _trx(trx),
|
: _trx(trx),
|
||||||
|
_baseVertexExpression(nullptr),
|
||||||
_tmpVar(nullptr),
|
_tmpVar(nullptr),
|
||||||
_ctx(new aql::FixedVarExpressionContext()),
|
_ctx(new aql::FixedVarExpressionContext()),
|
||||||
minDepth(1),
|
minDepth(1),
|
||||||
|
|
|
@ -2754,7 +2754,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
let stats = cursor.getExtra().stats;
|
let stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
} else {
|
||||||
assertEqual(stats.scannedIndex, 8);
|
assertEqual(stats.scannedIndex, 8);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 1);
|
assertEqual(stats.filtered, 1);
|
||||||
|
|
||||||
query = `
|
query = `
|
||||||
|
@ -2770,7 +2774,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
stats = cursor.getExtra().stats;
|
stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
} else {
|
||||||
assertEqual(stats.scannedIndex, 8);
|
assertEqual(stats.scannedIndex, 8);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 1);
|
assertEqual(stats.filtered, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2820,7 +2828,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
let stats = cursor.getExtra().stats;
|
let stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
} else {
|
||||||
assertEqual(stats.scannedIndex, 8);
|
assertEqual(stats.scannedIndex, 8);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 1);
|
assertEqual(stats.filtered, 1);
|
||||||
|
|
||||||
query = `
|
query = `
|
||||||
|
@ -2836,7 +2848,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
stats = cursor.getExtra().stats;
|
stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
} else {
|
||||||
assertEqual(stats.scannedIndex, 8);
|
assertEqual(stats.scannedIndex, 8);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 1);
|
assertEqual(stats.filtered, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2874,7 +2890,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
let stats = cursor.getExtra().stats;
|
let stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
assertEqual(stats.scannedIndex, 9);
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 5);
|
||||||
|
} else {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 2);
|
assertEqual(stats.filtered, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2912,7 +2932,11 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
let stats = cursor.getExtra().stats;
|
let stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
assertEqual(stats.scannedIndex, 9);
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 5);
|
||||||
|
} else {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 2);
|
assertEqual(stats.filtered, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2950,12 +2974,14 @@ function optimizeQuantifierSuite() {
|
||||||
|
|
||||||
let stats = cursor.getExtra().stats;
|
let stats = cursor.getExtra().stats;
|
||||||
assertEqual(stats.scannedFull, 0);
|
assertEqual(stats.scannedFull, 0);
|
||||||
assertEqual(stats.scannedIndex, 9);
|
if (isCluster) {
|
||||||
|
assertEqual(stats.scannedIndex, 5);
|
||||||
|
} else {
|
||||||
|
assertEqual(stats.scannedIndex, 7);
|
||||||
|
}
|
||||||
assertEqual(stats.filtered, 2);
|
assertEqual(stats.filtered, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
jsunity.run(namedGraphSuite);
|
jsunity.run(namedGraphSuite);
|
||||||
|
|
Loading…
Reference in New Issue