1
0
Fork 0

fixes for traversal and multi-modify

This commit is contained in:
Jan Steemann 2015-12-08 14:50:05 +01:00
parent 0a678263fb
commit ee6792dd6b
6 changed files with 85 additions and 9 deletions

View File

@ -123,7 +123,8 @@ Ast::Ast (Query* query)
_root(nullptr),
_queries(),
_writeCollections(),
_functionsMayAccessDocuments(false) {
_functionsMayAccessDocuments(false),
_containsTraversal(false) {
TRI_ASSERT(_query != nullptr);
@ -1230,6 +1231,8 @@ AstNode* Ast::createNodeTraversal (char const* vertexVarName,
TRI_ASSERT(node->numMembers() == 4);
_containsTraversal = true;
return node;
}
@ -1253,6 +1256,8 @@ AstNode* Ast::createNodeTraversal (char const* vertexVarName,
node->addMember(edgeVar);
TRI_ASSERT(node->numMembers() == 5);
_containsTraversal = true;
return node;
}
@ -1280,6 +1285,8 @@ AstNode* Ast::createNodeTraversal (char const* vertexVarName,
node->addMember(pathVar);
TRI_ASSERT(node->numMembers() == 6);
_containsTraversal = true;
return node;
}

View File

@ -202,6 +202,14 @@ namespace triagens {
return _functionsMayAccessDocuments;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the query contains a traversal
////////////////////////////////////////////////////////////////////////////////
bool containsTraversal () const {
return _containsTraversal;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the AST into JSON
/// the caller is responsible for freeing the JSON later
@ -998,6 +1006,12 @@ namespace triagens {
bool _functionsMayAccessDocuments;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the query contains a traversal
////////////////////////////////////////////////////////////////////////////////
bool _containsTraversal;
////////////////////////////////////////////////////////////////////////////////
/// @brief a singleton no-op node instance
////////////////////////////////////////////////////////////////////////////////

View File

@ -471,12 +471,18 @@ ModificationOptions ExecutionPlan::createModificationOptions (AstNode const* nod
// no functions in the query can access document data...
bool isReadWrite = false;
auto const collections = _ast->query()->collections();
if (_ast->containsTraversal()) {
// its unclear which collections the traversal will access
isReadWrite = true;
}
else {
auto const collections = _ast->query()->collections();
for (auto const& it : *(collections->collections())) {
if (it.second->isReadWrite) {
isReadWrite = true;
break;
for (auto const& it : *(collections->collections())) {
if (it.second->isReadWrite) {
isReadWrite = true;
break;
}
}
}

View File

@ -3686,6 +3686,12 @@ int triagens::aql::patchUpdateStatementsRule (Optimizer* opt,
modified = true;
}
}
if (type == EN::TRAVERSAL) {
// unclear what will be read by the traversal
modified = false;
break;
}
dep = dep->getFirstDependency();
}

View File

@ -683,10 +683,16 @@ function processQuery (query, explain) {
}
rc += " " +
keyword("IN") + " " +
node.minMaxDepth + " " + annotation("/* min..maxPathDepth */") + " " +
value(node.minMaxDepth) + " " + annotation("/* min..maxPathDepth */") + " " +
keyword("OUTBOUND") +
" '" + node.vertexId + "' " + annotation("/* Startnode */") + " " +
keyword("GRAPH") + " '" + node.graph + "'";
" '" + value(node.vertexId) + "' " + annotation("/* startnode */") + " ";
if (Array.isArray(node.graph)) {
rc += node.graph.map(function(g) { return collection(g); }).join(", ");
}
else {
rc += keyword("GRAPH") + " '" + value(node.graph) + "'";
}
traversalDetails.push(node);
if (node.hasOwnProperty('simpleExpressions')) {

View File

@ -73,6 +73,43 @@ function ahuacatlMultiModifySuite () {
c3 = null;
},
testTraversalAndModification : function () {
c1.insert({ _key: "1" });
c1.insert({ _key: "2" });
c1.insert({ _key: "3" });
c1.insert({ _key: "4" });
c3.insert(cn1 + "/1", cn1 + "/2", { });
c3.insert(cn1 + "/2", cn1 + "/3", { });
var q = "FOR v IN 1..99 OUTBOUND '" + cn1 + "/1' @@e REMOVE v._key IN @@cn";
var actual = AQL_EXECUTE(q, { "@cn": cn1, "@e": cn3 });
assertEqual([ ], actual.json);
assertEqual(2, actual.stats.writesExecuted);
assertEqual(2, c1.count());
assertTrue(c1.exists("1"));
assertTrue(c1.exists("4"));
assertEqual(2, c3.count());
},
testTraversalAndModificationBig : function () {
var i;
for (i = 1; i <= 2010; ++i) {
c1.insert({ _key: String(i) });
if (i !== 2010) {
c3.insert(cn1 + "/" + String(i), cn1 + "/" + String(i + 1), { });
}
}
var q = "FOR v IN 1..2010 OUTBOUND '" + cn1 + "/1' @@e REMOVE v._key IN @@cn";
var actual = AQL_EXECUTE(q, { "@cn": cn1, "@e": cn3 });
assertEqual([ ], actual.json);
assertEqual(2009, actual.stats.writesExecuted);
assertEqual(1, c1.count());
assertTrue(c1.exists("1"));
assertEqual(2009, c3.count());
},
testTraversalAfterModification : function () {
var q = "INSERT { _key: '1', foo: 'bar' } INTO @@cn FOR doc IN OUTBOUND 'v/1' @@e RETURN doc";
assertQueryError(errors.ERROR_QUERY_ACCESS_AFTER_MODIFICATION.code, q, { "@cn": cn1, "@e": cn3 });