mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' into vpack
This commit is contained in:
commit
61fe51072c
48
CHANGELOG
48
CHANGELOG
|
@ -7,6 +7,21 @@ v3.0.0 (XXXX-XX-XX)
|
|||
v2.8.0 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* fixes for AQL optimizer and traversal
|
||||
|
||||
* added `--create-collection-type` option to arangoimp
|
||||
|
||||
This allows specifying the type of the collection to be created when
|
||||
`--create-collection` is set to `true`.
|
||||
|
||||
* randomly shuffle available V8 contexts when picking one for an HTTP or scheduler
|
||||
task. This distributes requests more evenly across contexts so they can eventually
|
||||
be garbage-collected.
|
||||
|
||||
|
||||
v2.8.0-beta2 (2015-12-16)
|
||||
-------------------------
|
||||
|
||||
* added AQL query optimizer rule "sort-in-values"
|
||||
|
||||
This rule pre-sorts the right-hand side operand of the `IN` and `NOT IN`
|
||||
|
@ -293,9 +308,42 @@ v2.8.0-alpha1 (2015-12-03)
|
|||
re-enabled by explicitly setting the option `returnBodyOnError` to `false` (#1437)
|
||||
|
||||
|
||||
v2.7.4 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* randomly shuffle available V8 contexts when picking one for an HTTP or scheduler
|
||||
task. This distributes requests more evenly across contexts so they can eventually
|
||||
be garbage-collected.
|
||||
|
||||
* added the following attributes to the result of `collection.figures()` and the
|
||||
corresponding HTTP API at `PUT /_api/collection/<name>/figures`:
|
||||
|
||||
- `documentReferences`: The number of references to documents in datafiles
|
||||
that JavaScript code currently holds. This information can be used for
|
||||
debugging compaction and unload issues.
|
||||
- `waitingFor`: An optional string value that contains information about
|
||||
which object type is at the head of the collection's cleanup queue. This
|
||||
information can be used for debugging compaction and unload issues.
|
||||
- `compactionStatus.time`: The point in time the compaction for the collection
|
||||
was last executed. This information can be used for debugging compaction
|
||||
issues.
|
||||
- `compactionStatus.message`: The action that was performed when the compaction
|
||||
was last run for the collection. This information can be used for debugging
|
||||
compaction issues.
|
||||
|
||||
Note: `waitingFor` and `compactionStatus` may be empty when called on a coordinator
|
||||
in a cluster.
|
||||
|
||||
* the compaction will now provide queryable status info that can be used to track
|
||||
its progress. The compaction status is displayed in the web interface, too.
|
||||
|
||||
|
||||
v2.7.3 (2015-12-17)
|
||||
-------------------
|
||||
|
||||
* fixed some replication value conversion issues when replication applier properties
|
||||
were set via ArangoShell
|
||||
|
||||
* fixed disappearing of documents for collections transferred via `sync` or
|
||||
`syncCollection` if the collection was dropped right before synchronization
|
||||
and drop and (re-)create collection markers were located in the same WAL file
|
||||
|
|
|
@ -88,7 +88,7 @@ You have two options here, you can either use a managed graph (see [the graphs c
|
|||
- `edges`: an array of all edges on this path.
|
||||
- `IN` `MIN`..`MAX` `OUTBOUND` startVertex `GRAPH` graphName
|
||||
- `OUTBOUND|INBOUND|ANY` traversal will be done for outbound / inbound / inbound+outbound pointing edges
|
||||
- **startVertex**: one vertex where the traversal will originate from
|
||||
- **startVertex**: one vertex where the traversal will originate from, this can be specified in the form of an id string or in the form of a document with the attribute `_id`. All other values will lead to a warning and an empty result. If the specified id does not exist, the result is empty as well and there is no warning.
|
||||
- **graphName**: the name of a managed graph. It's vertex and edge collections will be looked up.
|
||||
- `MIN`: edges and vertices returned by this query will start at the traversal depth of `MIN` (thus edges and vertices below will not be returned). If not specified, defaults to `1`.
|
||||
- `MAX`: up to `MAX` length paths are traversed. If omitted in the query, `MAX` equals `MIN`. Thus only the vertices and edges in the range of `MIN` are returned.
|
||||
|
|
|
@ -335,12 +335,17 @@ void TraversalBlock::initializePaths (AqlItemBlock const* items) {
|
|||
if (! _usedConstant) {
|
||||
_usedConstant = true;
|
||||
auto pos = _vertexId.find("/");
|
||||
auto v(triagens::arango::traverser::VertexId(
|
||||
_resolver->getCollectionIdCluster(_vertexId.substr(0, pos).c_str()),
|
||||
_vertexId.c_str() + pos + 1
|
||||
));
|
||||
if (pos == std::string::npos) {
|
||||
_engine->getQuery()->registerWarning(TRI_ERROR_BAD_PARAMETER, "Invalid input for traversal: Only id strings or objects with _id are allowed");
|
||||
}
|
||||
else {
|
||||
auto v(triagens::arango::traverser::VertexId(
|
||||
_resolver->getCollectionIdCluster(_vertexId.substr(0, pos).c_str()),
|
||||
_vertexId.c_str() + pos + 1
|
||||
));
|
||||
|
||||
_traverser->setStartVertex(v);
|
||||
_traverser->setStartVertex(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -373,7 +378,7 @@ void TraversalBlock::initializePaths (AqlItemBlock const* items) {
|
|||
_traverser->setStartVertex(v);
|
||||
}
|
||||
else {
|
||||
_engine->getQuery()->registerWarning(TRI_ERROR_BAD_PARAMETER, "Invalid input for traversal: Only strings or objects with _id are allowed");
|
||||
_engine->getQuery()->registerWarning(TRI_ERROR_BAD_PARAMETER, "Invalid input for traversal: Only id strings or objects with _id are allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid start vertex. Must either be an _id string or an object with _id.");
|
||||
}
|
||||
_inVariable = nullptr;
|
||||
_vertexId = start->getStringValue();
|
||||
_vertexId = std::string(start->getStringValue(), start->getStringLength());;
|
||||
break;
|
||||
default:
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid start vertex. Must either be an _id string or an object with _id.");
|
||||
|
|
|
@ -438,6 +438,9 @@ ApplicationV8::V8Context* ApplicationV8::enterContext (TRI_vocbase_t* vocbase,
|
|||
|
||||
LOG_TRACE("found unused V8 context");
|
||||
TRI_ASSERT(! _freeContexts.empty());
|
||||
|
||||
// randomly shuffle free contexts so that different get contexts get used (and garbage collected)
|
||||
std::random_shuffle(_freeContexts.begin(), _freeContexts.end());
|
||||
|
||||
context = _freeContexts.back();
|
||||
TRI_ASSERT(context != nullptr);
|
||||
|
@ -692,8 +695,8 @@ void ApplicationV8::collectGarbage () {
|
|||
TRI_ASSERT(v8::Locker::IsLocked(isolate));
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
hasActiveExternals = v8g->hasActiveExternals();
|
||||
TRI_RunGarbageCollectionV8(isolate, 1.0);
|
||||
hasActiveExternals = v8g->hasActiveExternals();
|
||||
|
||||
localContext->Exit();
|
||||
}
|
||||
|
|
|
@ -50,16 +50,16 @@
|
|||
// --SECTION-- private constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static char const* ReasonNoDatafiles = "collection has no datafiles";
|
||||
static char const* ReasonCompactionBlocked = "existing compactor file is in the way and waiting to be processed";
|
||||
static char const* ReasonDatafileSmall = "datafile is small and will be merged with next";
|
||||
static char const* ReasonEmpty = "datafile contains data but collection is empty";
|
||||
static char const* ReasonOnlyDeletions = "datafile contains only deletion markers";
|
||||
static char const* ReasonDeadSize = "datafile contains much dead object space";
|
||||
static char const* ReasonDeadSizeShare = "datafile contains high share of dead objects";
|
||||
static char const* ReasonDeadCount = "datafile contains many dead objects";
|
||||
static char const* ReasonDeletionCount = "datafile contains many deletions";
|
||||
static char const* ReasonNothingToCompact = "no compaction opportunity found during inspection";
|
||||
static char const* ReasonNoDatafiles = "skipped compaction because collection has no datafiles";
|
||||
static char const* ReasonCompactionBlocked = "skipped compaction because existing compactor file is in the way and waits to be processed";
|
||||
static char const* ReasonDatafileSmall = "compacting datafile because it's small and will be merged with next";
|
||||
static char const* ReasonEmpty = "compacting datafile because it collection is empty";
|
||||
static char const* ReasonOnlyDeletions = "compacting datafile because it contains only deletion markers";
|
||||
static char const* ReasonDeadSize = "compacting datafile because it contains much dead object space";
|
||||
static char const* ReasonDeadSizeShare = "compacting datafile because it contains high share of dead objects";
|
||||
static char const* ReasonDeadCount = "compacting datafile because it contains many dead objects";
|
||||
static char const* ReasonDeletionCount = "compacting datafile because it contains many deletions";
|
||||
static char const* ReasonNothingToCompact = "checked datafiles, but no compaction opportunity found";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief minimum size of dead data (in bytes) in a datafile that will make
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
|
||||
<div class="contentDiv" id="arangoCollectionsContainer">
|
||||
<div id="userManagementThumbnailsIn" class="tileList">
|
||||
<div class="tileList">
|
||||
<div class="tile">
|
||||
<div class="fullBorderBox">
|
||||
<a href="#" id="createDatabase" class="add">
|
||||
|
|
|
@ -526,8 +526,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
var origin = window.location.href.split("/"),
|
||||
preUrl = origin[0] + '//' + origin[2] + '/' + origin[3] + '/_system/' + origin[5] + '/' + origin[6] + '/';
|
||||
|
||||
$.ajax(
|
||||
url + urlParams,
|
||||
preUrl + url + urlParams,
|
||||
{async: true}
|
||||
).done(
|
||||
function (d) {
|
||||
|
|
|
@ -13,21 +13,22 @@
|
|||
template: templateEngine.createTemplate("userManagementView.ejs"),
|
||||
|
||||
events: {
|
||||
"click #createUser" : "createUser",
|
||||
"click #submitCreateUser" : "submitCreateUser",
|
||||
"click #createUser" : "createUser",
|
||||
"click #submitCreateUser" : "submitCreateUser",
|
||||
// "click #deleteUser" : "removeUser",
|
||||
// "click #submitDeleteUser" : "submitDeleteUser",
|
||||
"click .editUser" : "editUser",
|
||||
"click .icon" : "editUser",
|
||||
"click #submitEditUser" : "submitEditUser",
|
||||
"click #userManagementToggle" : "toggleView",
|
||||
"keyup #userManagementSearchInput" : "search",
|
||||
"click #userManagementSearchSubmit" : "search",
|
||||
"click #callEditUserPassword" : "editUserPassword",
|
||||
"click #submitEditUserPassword" : "submitEditUserPassword",
|
||||
"click #submitEditCurrentUserProfile" : "submitEditCurrentUserProfile",
|
||||
"click .css-label" : "checkBoxes",
|
||||
"change #userSortDesc" : "sorting"
|
||||
// "click .editUser" : "editUser",
|
||||
// "click .icon" : "editUser",
|
||||
"click #userManagementThumbnailsIn .tile" : "editUser",
|
||||
"click #submitEditUser" : "submitEditUser",
|
||||
"click #userManagementToggle" : "toggleView",
|
||||
"keyup #userManagementSearchInput" : "search",
|
||||
"click #userManagementSearchSubmit" : "search",
|
||||
"click #callEditUserPassword" : "editUserPassword",
|
||||
"click #submitEditUserPassword" : "submitEditUserPassword",
|
||||
"click #submitEditCurrentUserProfile" : "submitEditCurrentUserProfile",
|
||||
"click .css-label" : "checkBoxes",
|
||||
"change #userSortDesc" : "sorting"
|
||||
|
||||
},
|
||||
|
||||
|
@ -202,6 +203,11 @@
|
|||
},
|
||||
|
||||
editUser : function(e) {
|
||||
|
||||
if ($(e.currentTarget).hasClass('tile')) {
|
||||
e.currentTarget = $(e.currentTarget).find('img');
|
||||
}
|
||||
|
||||
this.collection.fetch();
|
||||
var username = this.evaluateUserName($(e.currentTarget).attr("id"), '_edit-user');
|
||||
if (username === '') {
|
||||
|
|
|
@ -328,7 +328,7 @@
|
|||
bottom: 12.1% !important;
|
||||
left: 50%;
|
||||
margin-left: -($int-width) / 2;
|
||||
width: $int-width + 20px;
|
||||
width: $int-width + 20px !important;
|
||||
|
||||
.modal-body {
|
||||
// min-height: $dashboard-height;
|
||||
|
|
|
@ -766,6 +766,61 @@ function multiCollectionGraphSuite () {
|
|||
});
|
||||
},
|
||||
|
||||
testOtherCollectionAttributeAccessInput: function () {
|
||||
var query = "FOR y IN @@vCol "
|
||||
+ "FOR x IN OUTBOUND y._id @@eCol SORT x._id ASC RETURN x._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"@vCol": vn
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 6);
|
||||
assertEqual(result[0], vertex.B);
|
||||
assertEqual(result[1], vertex.B);
|
||||
assertEqual(result[2], vertex.C);
|
||||
assertEqual(result[3], vertex.D);
|
||||
assertEqual(result[4], vertex.E);
|
||||
assertEqual(result[5], vertex.F);
|
||||
},
|
||||
|
||||
testTraversalAttributeAccessInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "FOR y IN OUTBOUND x._id @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
},
|
||||
|
||||
testTraversalLetIdInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "LET next = x._id "
|
||||
+ "FOR y IN OUTBOUND next @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
},
|
||||
|
||||
testTraversalLetDocInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "LET next = x "
|
||||
+ "FOR y IN OUTBOUND next @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -847,62 +902,8 @@ function multiEdgeCollectionGraphSuite () {
|
|||
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
|
||||
assertEqual(jsonResult, result, query);
|
||||
});
|
||||
},
|
||||
|
||||
testOtherCollectionAttributeAccessInput: function () {
|
||||
var query = "FOR y IN @@vCol "
|
||||
+ "FOR x IN OUTBOUND y._id @@eCol SORT x._id ASC RETURN x._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"@vCol": vn
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 6);
|
||||
assertEqual(result[0], vertex.B);
|
||||
assertEqual(result[1], vertex.B);
|
||||
assertEqual(result[2], vertex.C);
|
||||
assertEqual(result[3], vertex.D);
|
||||
assertEqual(result[4], vertex.E);
|
||||
assertEqual(result[5], vertex.F);
|
||||
},
|
||||
|
||||
testTraversalAttributeAccessInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "FOR y IN OUTBOUND x._id @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
},
|
||||
|
||||
testTraversalLetIdInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "LET next = x._id "
|
||||
+ "FOR y IN OUTBOUND next @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
},
|
||||
|
||||
testTraversalLetDocInput: function () {
|
||||
var query = "FOR x IN OUTBOUND @startId @@eCol "
|
||||
+ "LET next = x "
|
||||
+ "FOR y IN OUTBOUND next @@eCol SORT y._id ASC RETURN y._id";
|
||||
var bindVars = {
|
||||
"@eCol": en,
|
||||
"startId": vertex.A
|
||||
};
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1027,11 +1028,11 @@ function potentialErrorsSuite () {
|
|||
"@eCol": en,
|
||||
"@vCol": vn
|
||||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 1);
|
||||
},
|
||||
|
||||
testStepsSubquery: function() {
|
||||
|
@ -1042,6 +1043,7 @@ function potentialErrorsSuite () {
|
|||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
fail();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
|
@ -1054,6 +1056,7 @@ function potentialErrorsSuite () {
|
|||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
fail();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
|
@ -1066,6 +1069,7 @@ function potentialErrorsSuite () {
|
|||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
fail();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
|
@ -1076,11 +1080,11 @@ function potentialErrorsSuite () {
|
|||
var bindVars = {
|
||||
"@eCol": en,
|
||||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 1);
|
||||
},
|
||||
|
||||
testCrazyStart4: function () {
|
||||
|
@ -1088,11 +1092,11 @@ function potentialErrorsSuite () {
|
|||
var bindVars = {
|
||||
"@eCol": en,
|
||||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 1);
|
||||
},
|
||||
|
||||
testCrazyStart5: function () {
|
||||
|
@ -1100,11 +1104,11 @@ function potentialErrorsSuite () {
|
|||
var bindVars = {
|
||||
"@eCol": en,
|
||||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 0);
|
||||
},
|
||||
|
||||
testCrazyStart6: function () {
|
||||
|
@ -1125,14 +1129,14 @@ function potentialErrorsSuite () {
|
|||
"@eCol": en,
|
||||
"@vCol": vn
|
||||
};
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 1);
|
||||
// Fix the query, just use the first value
|
||||
query = "FOR x IN OUTBOUND (FOR y IN @@vCol FILTER y._id == @startId RETURN y)[0] @@eCol RETURN x._id";
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 1);
|
||||
assertEqual(result[0], vertex.C);
|
||||
},
|
||||
|
@ -1143,19 +1147,15 @@ function potentialErrorsSuite () {
|
|||
"startId": vertex.A,
|
||||
"@eCol": en
|
||||
};
|
||||
// Fail because it is an array
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
var x = db._query(query, bindVars);
|
||||
var result = x.toArray();
|
||||
var extra = x.getExtra();
|
||||
assertEqual(result, []);
|
||||
assertEqual(extra.warnings.length, 1);
|
||||
// Actually use the string!
|
||||
query = "FOR x IN OUTBOUND (FOR y IN @@eCol FILTER y._id == @startId RETURN 'peter')[0] @@eCol RETURN x._id";
|
||||
try {
|
||||
db._query(query, bindVars).toArray();
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
result = db._query(query, bindVars).toArray();
|
||||
assertEqual(result.length, 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue