mirror of https://gitee.com/bigwinds/arangodb
fix execution of AQL traversal expressions when there are multiple conditions that refer to variables set outside the traversal
This commit is contained in:
parent
d07c3c848c
commit
57fa55921c
13
CHANGELOG
13
CHANGELOG
|
@ -1,7 +1,7 @@
|
|||
devel
|
||||
-----
|
||||
|
||||
* added a memory expection of V8 memory gets to low
|
||||
* added a memory expection in case V8 memory gets too low
|
||||
|
||||
* fixed epoch computation in hybrid logical clock
|
||||
|
||||
|
@ -43,7 +43,16 @@ devel
|
|||
* added module.context.createDocumentationRouter to replace module.context.apiDocumentation
|
||||
|
||||
|
||||
v3.0.5 (XXXX-XX-XX)
|
||||
v3.0.6 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* fix execution of AQL traversal expressions when there are multiple
|
||||
conditions that refer to variables set outside the traversal
|
||||
|
||||
* properly return HTTP 503 in JS actions when backend is gone
|
||||
|
||||
|
||||
v3.0.5 (2016-08-18)
|
||||
-------------------
|
||||
|
||||
* execute AQL ternary operator via C++ if possible
|
||||
|
|
|
@ -844,6 +844,7 @@ AqlValue Expression::executeSimpleExpressionReference(
|
|||
std::string msg("variable not found '");
|
||||
msg.append(v->name);
|
||||
msg.append("' in executeSimpleExpression()");
|
||||
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,14 @@ TraversalBlock::TraversalBlock(ExecutionEngine* engine, TraversalNode const* ep)
|
|||
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
|
||||
inRegsCur.emplace_back(it->second.registerId);
|
||||
}
|
||||
|
||||
for (auto const& v : ep->_conditionVariables) {
|
||||
inVarsCur.emplace_back(v);
|
||||
auto it = ep->getRegisterPlan()->varInfo.find(v->id);
|
||||
TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
|
||||
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
|
||||
inRegsCur.emplace_back(it->second.registerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,6 +178,7 @@ int TraversalBlock::initialize() {
|
|||
void TraversalBlock::executeExpressions() {
|
||||
DEBUG_BEGIN_BLOCK();
|
||||
AqlItemBlock* cur = _buffer.front();
|
||||
size_t index = 0;
|
||||
for (auto& map : *_expressions) {
|
||||
for (size_t i = 0; i < map.second.size(); ++i) {
|
||||
// Right now no inVars are allowed.
|
||||
|
@ -178,8 +187,8 @@ void TraversalBlock::executeExpressions() {
|
|||
if (it != nullptr && it->expression != nullptr) {
|
||||
// inVars and inRegs needs fixx
|
||||
bool mustDestroy;
|
||||
AqlValue a = it->expression->execute(_trx, cur, _pos, _inVars[i],
|
||||
_inRegs[i], mustDestroy);
|
||||
AqlValue a = it->expression->execute(_trx, cur, _pos, _inVars[index],
|
||||
_inRegs[index], mustDestroy);
|
||||
|
||||
AqlValueGuard guard(a, mustDestroy);
|
||||
|
||||
|
@ -196,6 +205,7 @@ void TraversalBlock::executeExpressions() {
|
|||
|
||||
it->compareTo.reset(builder);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
throwIfKilled(); // check if we were aborted
|
||||
|
|
|
@ -702,11 +702,10 @@ void TraversalNode::setCondition(arangodb::aql::Condition* condition) {
|
|||
Ast::getReferencedVariables(condition->root(), varsUsedByCondition);
|
||||
|
||||
for (auto const& oneVar : varsUsedByCondition) {
|
||||
if ((_vertexOutVariable != nullptr &&
|
||||
oneVar->id != _vertexOutVariable->id) &&
|
||||
(_edgeOutVariable != nullptr && oneVar->id != _edgeOutVariable->id) &&
|
||||
(_pathOutVariable != nullptr && oneVar->id != _pathOutVariable->id) &&
|
||||
(_inVariable != nullptr && oneVar->id != _inVariable->id)) {
|
||||
if ((_vertexOutVariable == nullptr || oneVar->id != _vertexOutVariable->id) &&
|
||||
(_edgeOutVariable == nullptr || oneVar->id != _edgeOutVariable->id) &&
|
||||
(_pathOutVariable == nullptr || oneVar->id != _pathOutVariable->id) &&
|
||||
(_inVariable == nullptr || oneVar->id != _inVariable->id)) {
|
||||
_conditionVariables.emplace_back(oneVar);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,56 @@ function optimizerRuleTestSuite () {
|
|||
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
||||
assertEqual(simplePlan[2].type, "NoResultsNode");
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test multiple conditions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCondVars1 : function () {
|
||||
var queries = [
|
||||
"LET data = (FOR i IN 1..1 RETURN i) FOR v, e, p IN 1..10 OUTBOUND data GRAPH '" + graphName + "' FILTER p.vertices[0]._id == '123' FILTER p.vertices[1]._id != null FILTER p.edges[0]._id IN data[*].foo.bar RETURN 1"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query);
|
||||
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
||||
assertEqual(0, AQL_EXECUTE(query).json.length);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test multiple conditions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCondVars2 : function () {
|
||||
var queries = [
|
||||
"LET data = (FOR i IN 1..1 RETURN i) FOR v, e, p IN 1..10 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.vertices[0]._id == '123' FILTER p.vertices[1]._id != null FILTER p.edges[0]._id IN data[*].foo.bar RETURN 1"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query);
|
||||
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
||||
assertEqual(0, AQL_EXECUTE(query).json.length);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test multiple conditions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCondVars3 : function () {
|
||||
var queries = [
|
||||
"LET data = (FOR i IN 1..1 RETURN i) FOR v, e, p IN 1..10 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.vertices[0]._id == '123' FILTER p.vertices[1]._id != null FILTER p.edges[0]._id IN data[*].foo.bar FILTER p.edges[1]._key IN data[*].bar.baz._id RETURN 1"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query);
|
||||
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
||||
assertEqual(0, AQL_EXECUTE(query).json.length);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue