mirror of https://gitee.com/bigwinds/arangodb
fix cross-collection queries in AQL
This commit is contained in:
parent
2263e959fe
commit
e06329db48
|
@ -306,7 +306,19 @@ namespace triagens {
|
||||||
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, cid, type);
|
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, cid, type);
|
||||||
|
|
||||||
if (collection == 0) {
|
if (collection == 0) {
|
||||||
return _setupError = TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
|
// adding an unknown collection...
|
||||||
|
int res = TRI_ERROR_NO_ERROR;
|
||||||
|
|
||||||
|
if (type == TRI_TRANSACTION_READ && this->isReadOnlyTransaction()) {
|
||||||
|
res = TRI_AddDelayedReadCollectionTransaction(this->_trx, cid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
return _setupError = res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
|
|
@ -427,7 +427,7 @@ void TRI_FreeTransactionContext (TRI_transaction_context_t* const context) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief free all data associated with a specific collection
|
/// @brief free all data associated with a specific collection
|
||||||
/// TODO: this function must be called for all collections that are dropped
|
/// this function gets called for all collections that are dropped
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const context,
|
void TRI_RemoveCollectionTransactionContext (TRI_transaction_context_t* const context,
|
||||||
|
@ -1158,7 +1158,6 @@ TRI_vocbase_col_t* TRI_CheckCollectionTransaction (TRI_transaction_t* const trx,
|
||||||
// the vector is sorted by collection names
|
// the vector is sorted by collection names
|
||||||
n = trx->_collections._length;
|
n = trx->_collections._length;
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
|
|
||||||
collection = TRI_AtVectorPointer(&trx->_collections, i);
|
collection = TRI_AtVectorPointer(&trx->_collections, i);
|
||||||
|
|
||||||
if (cid < collection->_cid) {
|
if (cid < collection->_cid) {
|
||||||
|
@ -1240,6 +1239,48 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief add a collection to an already running transaction
|
||||||
|
/// opens it and locks it in read-only mode
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_AddDelayedReadCollectionTransaction (TRI_transaction_t* const trx,
|
||||||
|
const TRI_transaction_cid_t cid) {
|
||||||
|
TRI_transaction_collection_t* collection;
|
||||||
|
size_t i, n;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
n = trx->_collections._length;
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
collection = TRI_AtVectorPointer(&trx->_collections, i);
|
||||||
|
|
||||||
|
if (cid < collection->_cid) {
|
||||||
|
// collection is not contained in vector
|
||||||
|
collection = CreateCollection(cid, TRI_TRANSACTION_READ);
|
||||||
|
if (collection == NULL) {
|
||||||
|
// out of memory
|
||||||
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_InsertVectorPointer(&trx->_collections, collection, i);
|
||||||
|
|
||||||
|
collection->_collection = TRI_UseCollectionByIdVocBase(trx->_context->_vocbase, collection->_cid);
|
||||||
|
if (collection->_collection == NULL) {
|
||||||
|
return TRI_errno();
|
||||||
|
}
|
||||||
|
|
||||||
|
res = LockCollection(collection, TRI_TRANSACTION_READ);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we should not get here. Otherwise this is a logic error
|
||||||
|
LOG_WARNING("logic error. should have inserted collection");
|
||||||
|
|
||||||
|
return TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief start a transaction
|
/// @brief start a transaction
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -401,6 +401,13 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const,
|
||||||
const TRI_transaction_cid_t,
|
const TRI_transaction_cid_t,
|
||||||
const TRI_transaction_type_e);
|
const TRI_transaction_type_e);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief add a collection to an already running transaction, read-only mode
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int TRI_AddDelayedReadCollectionTransaction (TRI_transaction_t* const,
|
||||||
|
const TRI_transaction_cid_t);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief request a lock for a collection
|
/// @brief request a lock for a collection
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -279,12 +279,14 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
|
||||||
TRI_document_collection_t* document;
|
TRI_document_collection_t* document;
|
||||||
TRI_vocbase_col_t* collection;
|
TRI_vocbase_col_t* collection;
|
||||||
TRI_vocbase_t* vocbase;
|
TRI_vocbase_t* vocbase;
|
||||||
|
TRI_voc_cid_t cid;
|
||||||
regmatch_t matches[3];
|
regmatch_t matches[3];
|
||||||
regex_t re;
|
regex_t re;
|
||||||
int res;
|
int res;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
collection = data;
|
collection = data;
|
||||||
|
cid = 0;
|
||||||
|
|
||||||
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
|
||||||
|
|
||||||
|
@ -308,6 +310,8 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cid = collection->_cid;
|
||||||
|
|
||||||
document = (TRI_document_collection_t*) collection->_collection;
|
document = (TRI_document_collection_t*) collection->_collection;
|
||||||
|
|
||||||
res = TRI_CloseDocumentCollection(document);
|
res = TRI_CloseDocumentCollection(document);
|
||||||
|
@ -432,6 +436,10 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cid > 0) {
|
||||||
|
TRI_RemoveCollectionTransactionContext(vocbase->_transactionContext, cid);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2697,7 +2697,7 @@ function TRAVERSAL_FUNC (func, vertexCollection, edgeCollection, startVertex, di
|
||||||
var v = null;
|
var v = null;
|
||||||
var result = [ ];
|
var result = [ ];
|
||||||
try {
|
try {
|
||||||
v = vertexCollection.document(startVertex);
|
v = INTERNAL.db._document(startVertex);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,14 +183,18 @@ function ahuacatlCrossCollection () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
testTraversal1 : function () {
|
testTraversal1 : function () {
|
||||||
var d1 = vertex1.save({ _key: "test1" });
|
var d1 = vertex1.save({ _key: "test1", a: 1 });
|
||||||
var d2 = vertex1.save({ _key: "test2" });
|
var d2 = vertex1.save({ _key: "test2", a: 2 });
|
||||||
var d3 = vertex2.save({ _key: "test3" });
|
var d3 = vertex2.save({ _key: "test3", a: 3 });
|
||||||
var e1 = edge.save(d1._id, d2._id, { });
|
var e1 = edge.save(d1._id, d2._id, { });
|
||||||
var e2 = edge.save(d2._id, d3._id, { });
|
var e2 = edge.save(d2._id, d3._id, { });
|
||||||
|
|
||||||
var actual = getQueryResults("FOR t IN TRAVERSAL(" + vn1 + ", " + en + ", " + JSON.stringify(d1._id) + ", 'outbound', { }) RETURN t");
|
var actual = getQueryResults("FOR t IN TRAVERSAL(" + vn1 + ", " + en + ", " + JSON.stringify(d1._id) + ", 'outbound', { }) RETURN t");
|
||||||
assertEqual(2, actual.length);
|
assertEqual(3, actual.length);
|
||||||
|
|
||||||
|
assertEqual(1, actual[0].vertex.a);
|
||||||
|
assertEqual(2, actual[1].vertex.a);
|
||||||
|
assertEqual(3, actual[2].vertex.a);
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -198,12 +202,16 @@ function ahuacatlCrossCollection () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
testTraversal2 : function () {
|
testTraversal2 : function () {
|
||||||
var d1 = vertex1.save({ _key: "test1" });
|
var d1 = vertex1.save({ _key: "test1", a: 1 });
|
||||||
var d2 = vertex2.save({ _key: "test2" });
|
var d2 = vertex2.save({ _key: "test2", a: 2 });
|
||||||
|
var d3 = vertex2.save({ _key: "test3", a: 3 });
|
||||||
var e1 = edge.save(d1._id, d2._id, { });
|
var e1 = edge.save(d1._id, d2._id, { });
|
||||||
|
var e2 = edge.save(d2._id, d3._id, { });
|
||||||
|
|
||||||
var actual = getQueryResults("FOR t IN TRAVERSAL(" + vn1 + ", " + en + ", " + JSON.stringify(d2._id) + ", 'outbound', { }) RETURN t");
|
var actual = getQueryResults("FOR t IN TRAVERSAL(" + vn1 + ", " + en + ", " + JSON.stringify(d2._id) + ", 'outbound', { }) RETURN t");
|
||||||
assertEqual(0, actual.length);
|
assertEqual(2, actual.length);
|
||||||
|
assertEqual(2, actual[0].vertex.a);
|
||||||
|
assertEqual(3, actual[1].vertex.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue