1
0
Fork 0

fix cross-collection queries in AQL

This commit is contained in:
Jan Steemann 2013-02-05 10:56:28 +01:00
parent 2263e959fe
commit e06329db48
6 changed files with 87 additions and 11 deletions

View File

@ -306,7 +306,19 @@ namespace triagens {
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, cid, type);
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;

View File

@ -427,7 +427,7 @@ void TRI_FreeTransactionContext (TRI_transaction_context_t* const context) {
////////////////////////////////////////////////////////////////////////////////
/// @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,
@ -1158,7 +1158,6 @@ TRI_vocbase_col_t* TRI_CheckCollectionTransaction (TRI_transaction_t* const trx,
// the vector is sorted by collection names
n = trx->_collections._length;
for (i = 0; i < n; ++i) {
collection = TRI_AtVectorPointer(&trx->_collections, i);
if (cid < collection->_cid) {
@ -1240,6 +1239,48 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
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
////////////////////////////////////////////////////////////////////////////////

View File

@ -401,6 +401,13 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const,
const TRI_transaction_cid_t,
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
////////////////////////////////////////////////////////////////////////////////

View File

@ -279,12 +279,14 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
TRI_document_collection_t* document;
TRI_vocbase_col_t* collection;
TRI_vocbase_t* vocbase;
TRI_voc_cid_t cid;
regmatch_t matches[3];
regex_t re;
int res;
size_t i;
collection = data;
cid = 0;
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
@ -308,6 +310,8 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
return false;
}
cid = collection->_cid;
document = (TRI_document_collection_t*) collection->_collection;
res = TRI_CloseDocumentCollection(document);
@ -432,6 +436,10 @@ static bool DropCollectionCallback (TRI_collection_t* col, void* data) {
regfree(&re);
}
if (cid > 0) {
TRI_RemoveCollectionTransactionContext(vocbase->_transactionContext, cid);
}
return true;
}

View File

@ -2697,7 +2697,7 @@ function TRAVERSAL_FUNC (func, vertexCollection, edgeCollection, startVertex, di
var v = null;
var result = [ ];
try {
v = vertexCollection.document(startVertex);
v = INTERNAL.db._document(startVertex);
}
catch (err) {
}

View File

@ -183,14 +183,18 @@ function ahuacatlCrossCollection () {
////////////////////////////////////////////////////////////////////////////////
testTraversal1 : function () {
var d1 = vertex1.save({ _key: "test1" });
var d2 = vertex1.save({ _key: "test2" });
var d3 = vertex2.save({ _key: "test3" });
var d1 = vertex1.save({ _key: "test1", a: 1 });
var d2 = vertex1.save({ _key: "test2", a: 2 });
var d3 = vertex2.save({ _key: "test3", a: 3 });
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(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 () {
var d1 = vertex1.save({ _key: "test1" });
var d2 = vertex2.save({ _key: "test2" });
var d1 = vertex1.save({ _key: "test1", a: 1 });
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 e2 = edge.save(d2._id, d3._id, { });
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);
}
};