mirror of https://gitee.com/bigwinds/arangodb
added possibility to kill JS traversals
This commit is contained in:
parent
075e1a0fb4
commit
d63f47e840
|
@ -316,18 +316,27 @@ TRI_json_t* Executor::executeExpression (Query* query,
|
|||
TRI_ASSERT(query != nullptr);
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
v8::Handle<v8::Value> result;
|
||||
auto old = v8g->_query;
|
||||
v8g->_query = static_cast<void*>(query);
|
||||
TRI_ASSERT(v8g->_query != nullptr);
|
||||
|
||||
try {
|
||||
v8g->_query = static_cast<void*>(query);
|
||||
TRI_ASSERT(v8g->_query != nullptr);
|
||||
|
||||
// execute the function
|
||||
v8::Handle<v8::Value> args;
|
||||
v8::Handle<v8::Value> result = v8::Handle<v8::Function>::Cast(func)->Call(v8::Object::New(isolate), 0, &args);
|
||||
// execute the function
|
||||
v8::Handle<v8::Value> args;
|
||||
result = v8::Handle<v8::Function>::Cast(func)->Call(v8::Object::New(isolate), 0, &args);
|
||||
|
||||
v8g->_query = old;
|
||||
v8g->_query = old;
|
||||
|
||||
// exit if execution raised an error
|
||||
HandleV8Error(tryCatch, result);
|
||||
// exit if execution raised an error
|
||||
HandleV8Error(tryCatch, result);
|
||||
}
|
||||
catch (...) {
|
||||
v8g->_query = old;
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
if (result->IsUndefined()) {
|
||||
// undefined => null
|
||||
|
@ -364,6 +373,7 @@ Function const* Executor::getFunctionByName (std::string const& name) {
|
|||
void Executor::HandleV8Error (v8::TryCatch& tryCatch,
|
||||
v8::Handle<v8::Value>& result) {
|
||||
ISOLATE;
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
// caught a V8 exception
|
||||
if (! tryCatch.CanContinue()) {
|
||||
|
|
|
@ -110,49 +110,52 @@ AqlValue V8Expression::execute (v8::Isolate* isolate,
|
|||
TRI_ASSERT(query != nullptr);
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
|
||||
v8::Handle<v8::Value> result;
|
||||
|
||||
auto old = v8g->_query;
|
||||
v8g->_query = static_cast<void*>(query);
|
||||
TRI_ASSERT(v8g->_query != nullptr);
|
||||
|
||||
// set function arguments
|
||||
v8::Handle<v8::Value> args[] = { values };
|
||||
try {
|
||||
v8g->_query = static_cast<void*>(query);
|
||||
TRI_ASSERT(v8g->_query != nullptr);
|
||||
|
||||
// execute the function
|
||||
v8::TryCatch tryCatch;
|
||||
// set function arguments
|
||||
v8::Handle<v8::Value> args[] = { values };
|
||||
|
||||
auto func = v8::Local<v8::Function>::New(isolate, _func);
|
||||
v8::Handle<v8::Value> result = func->Call(func, 1, args);
|
||||
// execute the function
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
v8g->_query = old;
|
||||
auto func = v8::Local<v8::Function>::New(isolate, _func);
|
||||
result = func->Call(func, 1, args);
|
||||
|
||||
Executor::HandleV8Error(tryCatch, result);
|
||||
v8g->_query = old;
|
||||
|
||||
Executor::HandleV8Error(tryCatch, result);
|
||||
}
|
||||
catch (...) {
|
||||
v8g->_query = old;
|
||||
throw;
|
||||
}
|
||||
|
||||
// no exception was thrown if we get here
|
||||
TRI_json_t* json = nullptr;
|
||||
std::unique_ptr<TRI_json_t> json;
|
||||
|
||||
if (result->IsUndefined()) {
|
||||
// expression does not have any (defined) value. replace with null
|
||||
json = TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE);
|
||||
json.reset(TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE));
|
||||
}
|
||||
else {
|
||||
// expression had a result. convert it to JSON
|
||||
json = TRI_ObjectToJson(isolate, result);
|
||||
// TODO: json = TRI_SimplifiedObjectToJson(isolate, result);
|
||||
json.reset(TRI_ObjectToJson(isolate, result));
|
||||
}
|
||||
|
||||
if (json == nullptr) {
|
||||
if (json.get() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
try {
|
||||
auto j = new triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return AqlValue(j);
|
||||
}
|
||||
catch (...) {
|
||||
// prevent memleak
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
throw;
|
||||
}
|
||||
auto j = new triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, json.get());
|
||||
json.release();
|
||||
return AqlValue(j);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -380,6 +380,7 @@ ApplicationV8::V8Context* ApplicationV8::enterContext (std::string const& name,
|
|||
|
||||
v8g->_vocbase = vocbase;
|
||||
v8g->_allowUseDatabase = allowUseDatabase;
|
||||
v8g->_query = nullptr;
|
||||
|
||||
LOG_TRACE("entering V8 context %d", (int) context->_id);
|
||||
context->handleGlobalContextMethods();
|
||||
|
@ -415,6 +416,7 @@ void ApplicationV8::exitContext (V8Context* context) {
|
|||
// check for cancelation requests
|
||||
bool const canceled = v8g->_canceled;
|
||||
v8g->_canceled = false;
|
||||
v8g->_query = nullptr;
|
||||
|
||||
// exit the context
|
||||
{
|
||||
|
|
|
@ -1599,6 +1599,21 @@ static void JS_QueriesKillAql (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a query is killed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void JS_QueryIsKilledAql (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
if (v8g->_query != nullptr && static_cast<triagens::aql::Query*>(v8g->_query)->killed()) {
|
||||
TRI_V8_RETURN_TRUE();
|
||||
}
|
||||
TRI_V8_RETURN_FALSE();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sleeps and checks for query abortion in between
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2913,6 +2928,7 @@ void TRI_InitV8VocBridge (v8::Isolate* isolate,
|
|||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERIES_SLOW"), JS_QueriesSlowAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERIES_KILL"), JS_QueriesKillAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_SLEEP"), JS_QuerySleepAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_IS_KILLED"), JS_QueryIsKilledAql, true);
|
||||
|
||||
TRI_InitV8replication(isolate, context, server, vocbase, loader, threadNumber, v8g);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.define("org/arangodb/graph/traversal", function(exports, module) {
|
||||
/*jshint strict: false, unused: false */
|
||||
/*global require, exports, ArangoClusterComm */
|
||||
/*global require, exports, ArangoClusterComm, AQL_QUERY_IS_KILLED */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Traversal "classes"
|
||||
|
@ -45,6 +45,30 @@ var ArangoTraverser;
|
|||
// --SECTION-- helper functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the query was aborted
|
||||
/// use the AQL_QUERY_IS_KILLED function on the server side, and a dummy
|
||||
/// function otherwise (ArangoShell etc.)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var throwIfAborted = function () {
|
||||
};
|
||||
|
||||
try {
|
||||
if (typeof AQL_QUERY_IS_KILLED === "function") {
|
||||
throwIfAborted = function () {
|
||||
if (AQL_QUERY_IS_KILLED()) {
|
||||
var err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_QUERY_KILLED.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_QUERY_KILLED.message;
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clone any object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -900,6 +924,8 @@ function breadthFirstSearch () {
|
|||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
if (current.visit === null || current.visit === undefined) {
|
||||
current.visit = false;
|
||||
|
||||
|
@ -1009,6 +1035,8 @@ function depthFirstSearch () {
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_TOO_MANY_ITERATIONS.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
// peek at the top of the stack
|
||||
var current = toVisit[toVisit.length - 1];
|
||||
|
@ -1153,6 +1181,8 @@ function dijkstraSearch () {
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_TOO_MANY_ITERATIONS.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
var currentNode = heap.pop();
|
||||
var i, n;
|
||||
|
@ -1291,6 +1321,8 @@ function astarSearch () {
|
|||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
var currentNode = heap.pop();
|
||||
var i, n;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jshint strict: false, unused: false */
|
||||
/*global require, exports, ArangoClusterComm */
|
||||
/*global require, exports, ArangoClusterComm, AQL_QUERY_IS_KILLED */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Traversal "classes"
|
||||
|
@ -44,6 +44,30 @@ var ArangoTraverser;
|
|||
// --SECTION-- helper functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the query was aborted
|
||||
/// use the AQL_QUERY_IS_KILLED function on the server side, and a dummy
|
||||
/// function otherwise (ArangoShell etc.)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var throwIfAborted = function () {
|
||||
};
|
||||
|
||||
try {
|
||||
if (typeof AQL_QUERY_IS_KILLED === "function") {
|
||||
throwIfAborted = function () {
|
||||
if (AQL_QUERY_IS_KILLED()) {
|
||||
var err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_QUERY_KILLED.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_QUERY_KILLED.message;
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clone any object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -899,6 +923,8 @@ function breadthFirstSearch () {
|
|||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
if (current.visit === null || current.visit === undefined) {
|
||||
current.visit = false;
|
||||
|
||||
|
@ -1008,6 +1034,8 @@ function depthFirstSearch () {
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_TOO_MANY_ITERATIONS.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
// peek at the top of the stack
|
||||
var current = toVisit[toVisit.length - 1];
|
||||
|
@ -1152,6 +1180,8 @@ function dijkstraSearch () {
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_TOO_MANY_ITERATIONS.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
var currentNode = heap.pop();
|
||||
var i, n;
|
||||
|
@ -1290,6 +1320,8 @@ function astarSearch () {
|
|||
throw err;
|
||||
}
|
||||
|
||||
throwIfAborted();
|
||||
|
||||
var currentNode = heap.pop();
|
||||
var i, n;
|
||||
|
||||
|
|
|
@ -5289,7 +5289,7 @@ function DOCUMENTS_BY_EXAMPLE (collectionList, example) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function RESOLVE_GRAPH_TO_COLLECTIONS(graph, options) {
|
||||
function RESOLVE_GRAPH_TO_COLLECTIONS (graph, options, funcname) {
|
||||
var collections = {};
|
||||
collections.fromCollections = [];
|
||||
collections.toCollection = [];
|
||||
|
@ -5329,7 +5329,7 @@ function RESOLVE_GRAPH_TO_COLLECTIONS(graph, options) {
|
|||
);
|
||||
}
|
||||
else {
|
||||
WARN("GRAPH_EDGES", INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
|
||||
WARN(funcname, INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
|
||||
// TODO: check if we need to return more data here
|
||||
return collections;
|
||||
}
|
||||
|
@ -5340,13 +5340,13 @@ function RESOLVE_GRAPH_TO_COLLECTIONS(graph, options) {
|
|||
return collections;
|
||||
}
|
||||
|
||||
function RESOLVE_GRAPH_TO_FROM_VERTICES (graphname, options) {
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphname), collections ;
|
||||
function RESOLVE_GRAPH_TO_FROM_VERTICES (graphname, options, funcname) {
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphname), collections;
|
||||
if (! graph) {
|
||||
THROW("GRAPH_EDGES", INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, "GRAPH_EDGES");
|
||||
THROW(funcname, INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, funcname);
|
||||
}
|
||||
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options);
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options, funcname);
|
||||
var removeDuplicates = function(elem, pos, self) {
|
||||
return self.indexOf(elem) === pos;
|
||||
};
|
||||
|
@ -5358,13 +5358,13 @@ function RESOLVE_GRAPH_TO_FROM_VERTICES (graphname, options) {
|
|||
);
|
||||
}
|
||||
|
||||
function RESOLVE_GRAPH_TO_TO_VERTICES (graphname, options) {
|
||||
function RESOLVE_GRAPH_TO_TO_VERTICES (graphname, options, funcname) {
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphname), collections ;
|
||||
if (! graph) {
|
||||
THROW("GRAPH_EDGES", INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, "GRAPH_EDGES");
|
||||
THROW(funcname, INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, funcname);
|
||||
}
|
||||
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options);
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options, funcname);
|
||||
var removeDuplicates = function(elem, pos, self) {
|
||||
return self.indexOf(elem) === pos;
|
||||
};
|
||||
|
@ -5374,34 +5374,18 @@ function RESOLVE_GRAPH_TO_TO_VERTICES (graphname, options) {
|
|||
);
|
||||
}
|
||||
|
||||
function RESOLVE_GRAPH_TO_EDGES (graphname, options) {
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphname), collections ;
|
||||
if (! graph) {
|
||||
THROW("GRAPH_EDGES", INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, "GRAPH_EDGES");
|
||||
}
|
||||
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options);
|
||||
var removeDuplicates = function(elem, pos, self) {
|
||||
return self.indexOf(elem) === pos;
|
||||
};
|
||||
|
||||
return DOCUMENTS_BY_EXAMPLE(
|
||||
collections.edgeCollections.filter(removeDuplicates), options.edgeExamples
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief GET ALL EDGE and VERTEX COLLECTION ACCORDING TO DIRECTION
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function RESOLVE_GRAPH_START_VERTICES (graphName, options) {
|
||||
function RESOLVE_GRAPH_START_VERTICES (graphName, options, funcname) {
|
||||
// check graph exists and load edgeDefintions
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphName), collections ;
|
||||
if (! graph) {
|
||||
THROW("GRAPH_EDGES", INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, "GRAPH_EDGES");
|
||||
THROW(funcname, INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, funcname);
|
||||
}
|
||||
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options);
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options, funcname);
|
||||
var removeDuplicates = function(elem, pos, self) {
|
||||
return self.indexOf(elem) === pos;
|
||||
};
|
||||
|
@ -5414,15 +5398,15 @@ function RESOLVE_GRAPH_START_VERTICES (graphName, options) {
|
|||
/// @brief GET ALL EDGE and VERTEX COLLECTION ACCORDING TO DIRECTION
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function RESOLVE_GRAPH_TO_DOCUMENTS (graphname, options) {
|
||||
function RESOLVE_GRAPH_TO_DOCUMENTS (graphname, options, funcname) {
|
||||
// check graph exists and load edgeDefintions
|
||||
|
||||
var graph = DOCUMENT_HANDLE("_graphs/" + graphname), collections ;
|
||||
if (! graph) {
|
||||
THROW("GRAPH_EDGES", INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, "GRAPH_EDGES");
|
||||
THROW(funcname, INTERNAL.errors.ERROR_GRAPH_INVALID_GRAPH, funcname);
|
||||
}
|
||||
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options);
|
||||
collections = RESOLVE_GRAPH_TO_COLLECTIONS(graph, options, funcname);
|
||||
var removeDuplicates = function(elem, pos, self) {
|
||||
return self.indexOf(elem) === pos;
|
||||
};
|
||||
|
@ -5862,7 +5846,7 @@ function CALCULATE_SHORTEST_PATHES_WITH_DIJKSTRA (graphName, options) {
|
|||
}
|
||||
}
|
||||
var result = [], fromVertices = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options),
|
||||
toVertices = RESOLVE_GRAPH_TO_TO_VERTICES(graphName, options);
|
||||
toVertices = RESOLVE_GRAPH_TO_TO_VERTICES(graphName, options, "GRAPH_SHORTEST_PATH");
|
||||
|
||||
var calculated = {};
|
||||
fromVertices.forEach(function (v) {
|
||||
|
@ -6014,7 +5998,7 @@ function AQL_GRAPH_SHORTEST_PATH (graphName,
|
|||
}
|
||||
|
||||
if (options.algorithm === "Floyd-Warshall") {
|
||||
var graph = RESOLVE_GRAPH_TO_DOCUMENTS(graphName, options);
|
||||
var graph = RESOLVE_GRAPH_TO_DOCUMENTS(graphName, options, "GRAPH_SHORTEST_PATH");
|
||||
return CALCULATE_SHORTEST_PATHES_WITH_FLOYD_WARSHALL(graph, options);
|
||||
}
|
||||
|
||||
|
@ -6123,7 +6107,7 @@ function AQL_GRAPH_TRAVERSAL (graphName,
|
|||
options.fromVertexExample = startVertexExample;
|
||||
options.direction = direction;
|
||||
|
||||
var startVertices = RESOLVE_GRAPH_START_VERTICES(graphName, options);
|
||||
var startVertices = RESOLVE_GRAPH_START_VERTICES(graphName, options, "GRAPH_TRAVERSAL");
|
||||
var factory = TRAVERSAL.generalGraphDatasourceFactory(graphName);
|
||||
|
||||
startVertices.forEach(function (f) {
|
||||
|
@ -6330,7 +6314,7 @@ function AQL_GRAPH_TRAVERSAL_TREE (graphName,
|
|||
options.fromVertexExample = startVertexExample;
|
||||
options.direction = direction;
|
||||
|
||||
var startVertices = RESOLVE_GRAPH_START_VERTICES(graphName, options);
|
||||
var startVertices = RESOLVE_GRAPH_START_VERTICES(graphName, options, "GRAPH_TRAVERSAL_TREE");
|
||||
var factory = TRAVERSAL.generalGraphDatasourceFactory(graphName);
|
||||
|
||||
startVertices.forEach(function (f) {
|
||||
|
@ -6529,7 +6513,7 @@ function AQL_GRAPH_NEIGHBORS (graphName,
|
|||
params.visitor = TRAVERSAL_NEIGHBOR_VISITOR;
|
||||
}
|
||||
|
||||
var fromVertices = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options);
|
||||
var fromVertices = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options, "GRAPH_NEIGHBORS");
|
||||
if (options.edgeExamples) {
|
||||
params.followEdges = options.edgeExamples;
|
||||
}
|
||||
|
@ -6730,7 +6714,7 @@ function AQL_GRAPH_VERTICES (graphName,
|
|||
}
|
||||
|
||||
options.fromVertexExample = vertexExamples;
|
||||
return RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options);
|
||||
return RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options, "GRAPH_VERTICES");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6923,8 +6907,8 @@ function AQL_GRAPH_COMMON_PROPERTIES (graphName,
|
|||
options.startVertexCollectionRestriction = options.vertex1CollectionRestriction;
|
||||
options.endVertexCollectionRestriction = options.vertex2CollectionRestriction;
|
||||
|
||||
var g = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options);
|
||||
var g2 = RESOLVE_GRAPH_TO_TO_VERTICES(graphName, options);
|
||||
var g = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options, "GRAPH_COMMON_PROPERTIES");
|
||||
var g2 = RESOLVE_GRAPH_TO_TO_VERTICES(graphName, options, "GRAPH_COMMON_PROPERTIES");
|
||||
var res = [];
|
||||
var t = {};
|
||||
g.forEach(function (n1) {
|
||||
|
|
Loading…
Reference in New Issue