diff --git a/arangod/CapConstraint/cap-constraint.c b/arangod/CapConstraint/cap-constraint.c index e82e87630f..99b3b43666 100644 --- a/arangod/CapConstraint/cap-constraint.c +++ b/arangod/CapConstraint/cap-constraint.c @@ -285,6 +285,7 @@ static int RemoveCapConstraint (TRI_index_t* idx, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateCapConstraint (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, size_t count, int64_t size) { TRI_cap_constraint_t* cap; @@ -299,7 +300,7 @@ TRI_index_t* TRI_CreateCapConstraint (struct TRI_primary_collection_s* primary, idx = &cap->base; idx->typeName = TypeNameCapConstraint; - TRI_InitIndex(idx, TRI_IDX_TYPE_CAP_CONSTRAINT, primary, false, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_CAP_CONSTRAINT, primary, false, true); idx->json = JsonCapConstraint; idx->removeIndex = RemoveIndexCapConstraint; diff --git a/arangod/CapConstraint/cap-constraint.h b/arangod/CapConstraint/cap-constraint.h index 95405525a5..15a59d774d 100644 --- a/arangod/CapConstraint/cap-constraint.h +++ b/arangod/CapConstraint/cap-constraint.h @@ -79,6 +79,7 @@ extern "C" { //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateCapConstraint (struct TRI_primary_collection_s*, + TRI_idx_iid_t, size_t, int64_t); diff --git a/arangod/Cluster/ClusterInfo.cpp b/arangod/Cluster/ClusterInfo.cpp index 48aecd2033..81122422f2 100644 --- a/arangod/Cluster/ClusterInfo.cpp +++ b/arangod/Cluster/ClusterInfo.cpp @@ -54,6 +54,40 @@ static inline int setErrormsg (int ourerrno, string& errorMsg) { errorMsg = TRI_errno_string(ourerrno); return ourerrno; } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief check whether the JSON returns an error +//////////////////////////////////////////////////////////////////////////////// + +static inline bool hasError (TRI_json_t const* json) { + TRI_json_t const* error = TRI_LookupArrayJson(json, "error"); + + return (TRI_IsBooleanJson(error) && error->_value._boolean); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief extract the error message from a JSON +//////////////////////////////////////////////////////////////////////////////// + +static string extractErrorMessage (string const& shardId, + TRI_json_t const* json) { + string msg = " shardID:" + shardId + ": "; + + // add error message text + TRI_json_t const* errorMessage = TRI_LookupArrayJson(json, "errorMessage"); + if (TRI_IsStringJson(errorMessage)) { + msg += string(errorMessage->_value._string.data, + errorMessage->_value._string.length - 1); + } + + // add error number + TRI_json_t const* errorNum = TRI_LookupArrayJson(json, "errorNum"); + if (TRI_IsNumberJson(errorNum)) { + msg += " (errNum=" + triagens::basics::StringUtils::itoa(static_cast(errorNum->_value._number)) + ")"; + } + + return msg; +} // ----------------------------------------------------------------------------- // --SECTION-- CollectionInfo class @@ -1539,6 +1573,16 @@ int ClusterInfo::ensureIndexCoordinator (string const& databaseName, for (size_t i = 0; i < indexes->_value._objects._length; ++i) { TRI_json_t const* v = TRI_LookupListJson(indexes, i); + + // check for errors + if (hasError(v)) { + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, newIndex); + string errorMsg = extractErrorMessage((*it).first, v); + + errorMsg = "Error during index creation: " + errorMsg; + return TRI_ERROR_ARANGO_INDEX_CREATION_FAILED; + } + TRI_json_t const* k = TRI_LookupArrayJson(v, "id"); if (! TRI_IsStringJson(k) || idString != string(k->_value._string.data)) { @@ -1643,14 +1687,24 @@ int ClusterInfo::dropIndexCoordinator (string const& databaseName, for (size_t i = 0; i < indexes->_value._objects._length; ++i) { TRI_json_t const* v = TRI_LookupListJson(indexes, i); TRI_json_t const* id = TRI_LookupArrayJson(v, "id"); + TRI_json_t const* type = TRI_LookupArrayJson(v, "type"); - if (! TRI_IsStringJson(id)) { + if (! TRI_IsStringJson(id) || ! TRI_IsStringJson(type)) { continue; } if (idString == string(id->_value._string.data)) { // found our index, ignore it when copying found = true; + + string const typeString(type->_value._string.data); + if (typeString == "primary" || typeString == "edge") { + // must not delete these index types + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, copy); + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, collectionJson); + return setErrormsg(TRI_ERROR_FORBIDDEN, errorMsg); + } + continue; } diff --git a/arangod/GeoIndex/geo-index.c b/arangod/GeoIndex/geo-index.c index be92bf0c21..538dd35f49 100644 --- a/arangod/GeoIndex/geo-index.c +++ b/arangod/GeoIndex/geo-index.c @@ -500,6 +500,7 @@ static int RemoveGeoIndex (TRI_index_t* idx, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, char const* locationName, TRI_shape_pid_t location, bool geoJson, @@ -515,7 +516,7 @@ TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s* primary, TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE); idx->typeName = TypeNameGeo1Index; - TRI_InitIndex(idx, TRI_IDX_TYPE_GEO1_INDEX, primary, unique, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO1_INDEX, primary, unique, true); idx->_ignoreNull = ignoreNull; @@ -553,6 +554,7 @@ TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s* primary, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateGeo2Index (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, char const* latitudeName, TRI_shape_pid_t latitude, char const* longitudeName, @@ -570,7 +572,7 @@ TRI_index_t* TRI_CreateGeo2Index (struct TRI_primary_collection_s* primary, TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE); idx->typeName = TypeNameGeo2Index; - TRI_InitIndex(idx, TRI_IDX_TYPE_GEO2_INDEX, primary, unique, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO2_INDEX, primary, unique, true); idx->_ignoreNull = ignoreNull; diff --git a/arangod/GeoIndex/geo-index.h b/arangod/GeoIndex/geo-index.h index 54346f94b0..245b0fa491 100644 --- a/arangod/GeoIndex/geo-index.h +++ b/arangod/GeoIndex/geo-index.h @@ -53,24 +53,26 @@ extern "C" { /// @brief creates a geo-index for lists //////////////////////////////////////////////////////////////////////////////// -TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s* collection, - char const* locationName, - TRI_shape_pid_t location, - bool geoJson, - bool constraint, - bool ignoreNull); +TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s*, + TRI_idx_iid_t, + char const*, + TRI_shape_pid_t, + bool, + bool, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief creates a geo-index for arrays //////////////////////////////////////////////////////////////////////////////// -TRI_index_t* TRI_CreateGeo2Index (struct TRI_primary_collection_s* collection, - char const* latitudeName, - TRI_shape_pid_t latitude, - char const* longitudeName, - TRI_shape_pid_t longitude, - bool constraint, - bool ignoreNull); +TRI_index_t* TRI_CreateGeo2Index (struct TRI_primary_collection_s*, + TRI_idx_iid_t, + char const*, + TRI_shape_pid_t , + char const*, + TRI_shape_pid_t, + bool, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief frees the memory allocated, but does not free the pointer diff --git a/arangod/HashIndex/hash-index.c b/arangod/HashIndex/hash-index.c index ca96a81d21..732ed7f064 100644 --- a/arangod/HashIndex/hash-index.c +++ b/arangod/HashIndex/hash-index.c @@ -576,6 +576,7 @@ static int RemoveHashIndex (TRI_index_t* idx, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateHashIndex (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, TRI_vector_pointer_t* fields, TRI_vector_t* paths, bool unique, @@ -592,7 +593,7 @@ TRI_index_t* TRI_CreateHashIndex (struct TRI_primary_collection_s* primary, idx = &hashIndex->base; idx->typeName = TypeNameHashIndex; - TRI_InitIndex(idx, TRI_IDX_TYPE_HASH_INDEX, primary, unique, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_HASH_INDEX, primary, unique, true); idx->json = JsonHashIndex; idx->insert = InsertHashIndex; diff --git a/arangod/HashIndex/hash-index.h b/arangod/HashIndex/hash-index.h index 9ebea0f2a7..885f81daa3 100644 --- a/arangod/HashIndex/hash-index.h +++ b/arangod/HashIndex/hash-index.h @@ -99,23 +99,24 @@ TRI_hash_index_t; /// @brief creates a hash index //////////////////////////////////////////////////////////////////////////////// -TRI_index_t* TRI_CreateHashIndex (struct TRI_primary_collection_s* collection, - TRI_vector_pointer_t* fields, - TRI_vector_t* paths, - bool unique, - size_t initialDocumentCount); +TRI_index_t* TRI_CreateHashIndex (struct TRI_primary_collection_s*, + TRI_idx_iid_t, + TRI_vector_pointer_t*, + TRI_vector_t*, + bool, + size_t); //////////////////////////////////////////////////////////////////////////////// /// @brief frees the memory allocated, but does not free the pointer //////////////////////////////////////////////////////////////////////////////// -void TRI_DestroyHashIndex (TRI_index_t* idx); +void TRI_DestroyHashIndex (TRI_index_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief frees the memory allocated and frees the pointer //////////////////////////////////////////////////////////////////////////////// -void TRI_FreeHashIndex (TRI_index_t* idx); +void TRI_FreeHashIndex (TRI_index_t*); //////////////////////////////////////////////////////////////////////////////// /// @} @@ -134,8 +135,8 @@ void TRI_FreeHashIndex (TRI_index_t* idx); /// @brief locates entries in the hash index given shaped json objects //////////////////////////////////////////////////////////////////////////////// -TRI_index_result_t TRI_LookupHashIndex (TRI_index_t* idx, - struct TRI_index_search_value_s* searchValue); +TRI_index_result_t TRI_LookupHashIndex (TRI_index_t*, + struct TRI_index_search_value_s*); //////////////////////////////////////////////////////////////////////////////// /// @} diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 765f239d41..7a85030605 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -1086,7 +1086,8 @@ static int EnhanceJsonIndexCap (v8::Handle const& obj, //////////////////////////////////////////////////////////////////////////////// static int EnhanceIndexJson (v8::Arguments const& argv, - TRI_json_t*& json) { + TRI_json_t*& json, + bool create) { v8::Handle obj = argv[0].As(); // extract index type @@ -1104,6 +1105,14 @@ static int EnhanceIndexJson (v8::Arguments const& argv, if (type == TRI_IDX_TYPE_UNKNOWN) { return TRI_ERROR_BAD_PARAMETER; } + + if (create) { + if (type == TRI_IDX_TYPE_PRIMARY_INDEX || + type == TRI_IDX_TYPE_EDGE_INDEX) { + // creating these indexes is forbidden + return TRI_ERROR_FORBIDDEN; + } + } json = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE); @@ -1554,7 +1563,7 @@ static v8::Handle EnsureIndex (v8::Arguments const& argv, } TRI_json_t* json = 0; - int res = EnhanceIndexJson(argv, json); + int res = EnhanceIndexJson(argv, json, create); if (res != TRI_ERROR_NO_ERROR) { if (json != 0) { @@ -2738,7 +2747,7 @@ static v8::Handle CreateCollectionCoordinator ( ClusterInfo* ci = ClusterInfo::instance(); // fetch a unique id for the new collection plus one for each shard to create - uint64_t id = ci->uniqid(1 + numberOfShards); + const uint64_t id = ci->uniqid(1 + numberOfShards); // collection id is the first unique id we got const string cid = StringUtils::itoa(id); @@ -2789,6 +2798,46 @@ static v8::Handle CreateCollectionCoordinator ( TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "shardKeys", JsonHelper::stringList(TRI_UNKNOWN_MEM_ZONE, shardKeys)); TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "shards", JsonHelper::stringObject(TRI_UNKNOWN_MEM_ZONE, shards)); + TRI_json_t* indexes = TRI_CreateListJson(TRI_UNKNOWN_MEM_ZONE); + if (indexes == 0) { + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + TRI_V8_EXCEPTION(scope, TRI_ERROR_OUT_OF_MEMORY); + } + + // create a dummy primary index + TRI_index_t* idx = TRI_CreatePrimaryIndex(0); + + if (idx == 0) { + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, indexes); + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + TRI_V8_EXCEPTION(scope, TRI_ERROR_OUT_OF_MEMORY); + } + + TRI_json_t* idxJson = idx->json(idx); + TRI_FreeIndex(idx); + + TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, indexes, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, idxJson)); + TRI_FreeJson(TRI_CORE_MEM_ZONE, idxJson); + + if (collectionType == TRI_COL_TYPE_EDGE) { + // create a dummy edge index + idx = TRI_CreateEdgeIndex(0, id); + + if (idx == 0) { + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, indexes); + TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + TRI_V8_EXCEPTION(scope, TRI_ERROR_OUT_OF_MEMORY); + } + + idxJson = idx->json(idx); + TRI_FreeIndex(idx); + + TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, indexes, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, idxJson)); + TRI_FreeJson(TRI_CORE_MEM_ZONE, idxJson); + } + + TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "indexes", indexes); + string errorMsg; int myerrno = ci->createCollectionCoordinator( databaseName, cid, numberOfShards, json, @@ -6041,8 +6090,10 @@ static v8::Handle JS_DropIndexVocbaseCol (v8::Arguments const& argv) } } - if (idx->_iid == 0) { - return scope.Close(v8::False()); + if (idx->_iid == 0 || + idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX || + idx->_type == TRI_IDX_TYPE_EDGE_INDEX) { + TRI_V8_EXCEPTION(scope, TRI_ERROR_FORBIDDEN); } // ............................................................................. diff --git a/arangod/VocBase/document-collection.c b/arangod/VocBase/document-collection.c index a08f61e24b..a9ca0627ae 100644 --- a/arangod/VocBase/document-collection.c +++ b/arangod/VocBase/document-collection.c @@ -2814,7 +2814,7 @@ static bool InitDocumentCollection (TRI_document_collection_t* document, if (document->base.base._info._type == TRI_COL_TYPE_EDGE) { TRI_index_t* edgesIndex; - edgesIndex = TRI_CreateEdgeIndex(&document->base); + edgesIndex = TRI_CreateEdgeIndex(&document->base, document->base.base._info._cid); if (edgesIndex == NULL) { TRI_FreeIndex(primaryIndex); @@ -3670,7 +3670,7 @@ static bool DropIndex (TRI_document_collection_t* document, if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX || idx->_type == TRI_IDX_TYPE_EDGE_INDEX) { // cannot remove these index types - continue; + break; } if (idx->_iid == iid) { @@ -4310,7 +4310,7 @@ static TRI_index_t* CreateCapConstraintDocumentCollection (TRI_document_collecti } // create a new index - idx = TRI_CreateCapConstraint(primary, count, size); + idx = TRI_CreateCapConstraint(primary, iid, count, size); if (idx == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); @@ -4318,10 +4318,6 @@ static TRI_index_t* CreateCapConstraintDocumentCollection (TRI_document_collecti return NULL; } - if (iid) { - idx->_iid = iid; - } - // initialises the index with all existing documents res = FillIndex(document, idx); @@ -4579,14 +4575,14 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t* // create a new index if (location != NULL) { - idx = TRI_CreateGeo1Index(primary, location, loc, geoJson, unique, ignoreNull); + idx = TRI_CreateGeo1Index(primary, iid, location, loc, geoJson, unique, ignoreNull); LOG_TRACE("created geo-index for location '%s': %ld", location, (unsigned long) loc); } else if (longitude != NULL && latitude != NULL) { - idx = TRI_CreateGeo2Index(primary, latitude, lat, longitude, lon, unique, ignoreNull); + idx = TRI_CreateGeo2Index(primary, iid, latitude, lat, longitude, lon, unique, ignoreNull); LOG_TRACE("created geo-index for location '%s': %ld, %ld", location, @@ -4599,10 +4595,6 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t* return NULL; } - if (iid) { - idx->_iid = iid; - } - // initialises the index with all existing documents res = FillIndex(document, idx); @@ -5049,6 +5041,7 @@ static TRI_index_t* CreateHashIndexDocumentCollection (TRI_document_collection_t // create the hash index. we'll provide it with the current number of documents // in the collection so the index can do a sensible memory preallocation idx = TRI_CreateHashIndex(&document->base, + iid, &fields, &paths, unique, @@ -5065,11 +5058,6 @@ static TRI_index_t* CreateHashIndexDocumentCollection (TRI_document_collection_t TRI_DestroyVector(&paths); TRI_DestroyVectorPointer(&fields); - // if index id given, use it otherwise use the default. - if (iid) { - idx->_iid = iid; - } - // initialises the index with all existing documents res = FillIndex(document, idx); @@ -5270,7 +5258,7 @@ static TRI_index_t* CreateSkiplistIndexDocumentCollection (TRI_document_collecti } // Create the skiplist index - idx = TRI_CreateSkiplistIndex(&document->base, &fields, &paths, unique); + idx = TRI_CreateSkiplistIndex(&document->base, iid, &fields, &paths, unique); if (idx == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); @@ -5281,11 +5269,6 @@ static TRI_index_t* CreateSkiplistIndexDocumentCollection (TRI_document_collecti TRI_DestroyVector(&paths); TRI_DestroyVectorPointer(&fields); - // If index id given, use it otherwise use the default. - if (iid) { - idx->_iid = iid; - } - // initialises the index with all existing documents res = FillIndex(document, idx); @@ -5506,18 +5489,13 @@ static TRI_index_t* CreateFulltextIndexDocumentCollection (TRI_document_collecti } // Create the fulltext index - idx = TRI_CreateFulltextIndex(&document->base, attributeName, indexSubstrings, minWordLength); + idx = TRI_CreateFulltextIndex(&document->base, iid, attributeName, indexSubstrings, minWordLength); if (idx == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } - // If index id given, use it otherwise use the default. - if (iid) { - idx->_iid = iid; - } - // initialises the index with all existing documents res = FillIndex(document, idx); @@ -5722,13 +5700,13 @@ TRI_index_t* TRI_EnsureFulltextIndexDocumentCollection (TRI_document_collection_ //////////////////////////////////////////////////////////////////////////////// static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collection_t* document, - const TRI_vector_pointer_t* attributes, - const TRI_vector_pointer_t* values, - TRI_idx_iid_t iid, - bool supportUndef, - bool* created, - int* errorNum, - char** errorStr) { + const TRI_vector_pointer_t* attributes, + const TRI_vector_pointer_t* values, + TRI_idx_iid_t iid, + bool supportUndef, + bool* created, + int* errorNum, + char** errorStr) { TRI_index_t* idx; TRI_vector_pointer_t fields; TRI_vector_t paths; @@ -5780,7 +5758,7 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti // Create the bitarray index // ........................................................................... - idx = TRI_CreateBitarrayIndex(&document->base, &fields, &paths, (TRI_vector_pointer_t*)(values), supportUndef, errorNum, errorStr); + idx = TRI_CreateBitarrayIndex(&document->base, iid, &fields, &paths, (TRI_vector_pointer_t*)(values), supportUndef, errorNum, errorStr); if (idx == NULL) { TRI_DestroyVector(&paths); @@ -5789,7 +5767,6 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti return NULL; } - // ........................................................................... // release memory allocated to fields & paths vectors // ........................................................................... @@ -5797,16 +5774,6 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti TRI_DestroyVector(&paths); TRI_DestroyVectorPointer(&fields); - - // ........................................................................... - // If an index id given, use it otherwise use the default (generate one) - // ........................................................................... - - if (iid) { - idx->_iid = iid; - } - - // ........................................................................... // initialises the index with all existing documents // ........................................................................... @@ -5827,7 +5794,6 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti return NULL; } - // ........................................................................... // store index within the collection and return // ........................................................................... diff --git a/arangod/VocBase/index.c b/arangod/VocBase/index.c index f126d0d6c6..8c95cc9e56 100644 --- a/arangod/VocBase/index.c +++ b/arangod/VocBase/index.c @@ -67,13 +67,26 @@ //////////////////////////////////////////////////////////////////////////////// void TRI_InitIndex (TRI_index_t* idx, - const TRI_idx_type_e type, + TRI_idx_iid_t iid, + TRI_idx_type_e type, struct TRI_primary_collection_s* primary, bool unique, bool needsFullCoverage) { + // note: primary can be NULL assert(idx != NULL); - idx->_iid = TRI_NewTickServer(); + if (iid > 0) { + // use iid if specified + idx->_iid = iid; + } + else if (type == TRI_IDX_TYPE_PRIMARY_INDEX) { + // override iid + idx->_iid = 0; + } + else { + idx->_iid = TRI_NewTickServer(); + } + idx->_type = type; idx->_collection = primary; idx->_unique = unique; @@ -597,18 +610,21 @@ TRI_index_t* TRI_CreatePrimaryIndex (struct TRI_primary_collection_s* primary) { TRI_index_t* idx; char* id; + // note: primary can be NULL + // create primary index idx = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_index_t), false); + if (idx == NULL) { + return NULL; + } + id = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, "_id"); TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE); TRI_PushBackVectorString(&idx->_fields, id); idx->typeName = TypeNamePrimary; - TRI_InitIndex(idx, TRI_IDX_TYPE_PRIMARY_INDEX, primary, true, true); - - // override iid - idx->_iid = 0; + TRI_InitIndex(idx, 0, TRI_IDX_TYPE_PRIMARY_INDEX, primary, true, true); idx->json = JsonPrimary; idx->insert = InsertPrimary; @@ -890,7 +906,8 @@ static TRI_json_t* JsonEdge (TRI_index_t* idx) { /// @brief create the edge index //////////////////////////////////////////////////////////////////////////////// -TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary) { +TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid) { TRI_edge_index_t* edgeIndex; TRI_index_t* idx; char* id; @@ -924,7 +941,7 @@ TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary) { TRI_PushBackVectorString(&idx->_fields, id); idx->typeName = TypeNameEdge; - TRI_InitIndex(idx, TRI_IDX_TYPE_EDGE_INDEX, primary, false, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_EDGE_INDEX, primary, false, true); idx->json = JsonEdge; idx->insert = InsertEdge; @@ -1485,6 +1502,7 @@ static int RemoveSkiplistIndex (TRI_index_t* idx, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateSkiplistIndex (TRI_primary_collection_t* primary, + TRI_idx_iid_t iid, TRI_vector_pointer_t* fields, TRI_vector_t* paths, bool unique) { @@ -1503,7 +1521,7 @@ TRI_index_t* TRI_CreateSkiplistIndex (TRI_primary_collection_t* primary, idx = &skiplistIndex->base; idx->typeName = TypeNameSkiplistIndex; - TRI_InitIndex(idx, TRI_IDX_TYPE_SKIPLIST_INDEX, primary, unique, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_SKIPLIST_INDEX, primary, unique, true); idx->json = JsonSkiplistIndex; idx->insert = InsertSkiplistIndex; @@ -1816,6 +1834,7 @@ static int CleanupFulltextIndex (TRI_index_t* idx) { //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, const char* attributeName, const bool indexSubstrings, int minWordLength) { @@ -1846,7 +1865,7 @@ TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s* primary, idx = &fulltextIndex->base; idx->typeName = TypeNameFulltextIndex; - TRI_InitIndex(idx, TRI_IDX_TYPE_FULLTEXT_INDEX, primary, false, true); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_FULLTEXT_INDEX, primary, false, true); idx->json = JsonFulltextIndex; idx->insert = InsertFulltextIndex; @@ -2492,6 +2511,7 @@ static int RemoveBitarrayIndex (TRI_index_t* idx, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateBitarrayIndex (struct TRI_primary_collection_s* primary, + TRI_idx_iid_t iid, TRI_vector_pointer_t* fields, TRI_vector_t* paths, TRI_vector_pointer_t* values, @@ -2561,7 +2581,7 @@ TRI_index_t* TRI_CreateBitarrayIndex (struct TRI_primary_collection_s* primary, idx = &baIndex->base; idx->typeName = TypeNameBitarrayIndex; - TRI_InitIndex(idx, TRI_IDX_TYPE_BITARRAY_INDEX, primary, false, false); + TRI_InitIndex(idx, iid, TRI_IDX_TYPE_BITARRAY_INDEX, primary, false, false); idx->json = JsonBitarrayIndex; idx->insert = InsertBitarrayIndex; diff --git a/arangod/VocBase/index.h b/arangod/VocBase/index.h index af4173afff..5fbf143bab 100644 --- a/arangod/VocBase/index.h +++ b/arangod/VocBase/index.h @@ -282,8 +282,9 @@ TRI_index_search_value_t; /// @brief initialise basic index properties //////////////////////////////////////////////////////////////////////////////// -void TRI_InitIndex (TRI_index_t*, - const TRI_idx_type_e, +void TRI_InitIndex (TRI_index_t*, + TRI_idx_iid_t, + TRI_idx_type_e, struct TRI_primary_collection_s*, bool, bool); @@ -441,7 +442,8 @@ void TRI_FreePrimaryIndex (TRI_index_t*); /// @brief create the edge index //////////////////////////////////////////////////////////////////////////////// -TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s*); +TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s*, + TRI_idx_iid_t); //////////////////////////////////////////////////////////////////////////////// /// @brief destroys an edge index, but does not free the pointer @@ -480,9 +482,10 @@ TRI_skiplist_iterator_t* TRI_LookupSkiplistIndex (TRI_index_t*, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateSkiplistIndex (struct TRI_primary_collection_s*, - TRI_vector_pointer_t* fields, - TRI_vector_t* paths, - bool unique); + TRI_idx_iid_t, + TRI_vector_pointer_t*, + TRI_vector_t*, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief frees the memory allocated, but does not free the pointer @@ -521,6 +524,7 @@ struct TRI_doc_mptr_s** TRI_LookupFulltextIndex (TRI_index_t*, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s*, + TRI_idx_iid_t, const char*, const bool, int); @@ -568,6 +572,7 @@ TRI_index_iterator_t* TRI_LookupBitarrayIndex (TRI_index_t*, //////////////////////////////////////////////////////////////////////////////// TRI_index_t* TRI_CreateBitarrayIndex (struct TRI_primary_collection_s*, + TRI_idx_iid_t, TRI_vector_pointer_t*, TRI_vector_t*, TRI_vector_pointer_t*, diff --git a/js/apps/system/aardvark/frontend/js/bootstrap/errors.js b/js/apps/system/aardvark/frontend/js/bootstrap/errors.js index 99d97f8a47..d9d7baa5b3 100644 --- a/js/apps/system/aardvark/frontend/js/bootstrap/errors.js +++ b/js/apps/system/aardvark/frontend/js/bootstrap/errors.js @@ -95,6 +95,7 @@ "ERROR_ARANGO_INVALID_KEY_GENERATOR" : { "code" : 1232, "message" : "invalid key generator" }, "ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE" : { "code" : 1233, "message" : "edge attribute missing" }, "ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING" : { "code" : 1234, "message" : "index insertion warning - attribute missing in document" }, + "ERROR_ARANGO_INDEX_CREATION_FAILED" : { "code" : 1235, "message" : "index creation failed" }, "ERROR_ARANGO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" }, "ERROR_REPLICATION_NO_RESPONSE" : { "code" : 1400, "message" : "no response" }, "ERROR_REPLICATION_INVALID_RESPONSE" : { "code" : 1401, "message" : "invalid response" }, diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index 99d97f8a47..d9d7baa5b3 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -95,6 +95,7 @@ "ERROR_ARANGO_INVALID_KEY_GENERATOR" : { "code" : 1232, "message" : "invalid key generator" }, "ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE" : { "code" : 1233, "message" : "edge attribute missing" }, "ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING" : { "code" : 1234, "message" : "index insertion warning - attribute missing in document" }, + "ERROR_ARANGO_INDEX_CREATION_FAILED" : { "code" : 1235, "message" : "index creation failed" }, "ERROR_ARANGO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" }, "ERROR_REPLICATION_NO_RESPONSE" : { "code" : 1400, "message" : "no response" }, "ERROR_REPLICATION_INVALID_RESPONSE" : { "code" : 1401, "message" : "invalid response" }, diff --git a/js/server/modules/org/arangodb/cluster.js b/js/server/modules/org/arangodb/cluster.js index b1a03018fe..7b6ef801e3 100644 --- a/js/server/modules/org/arangodb/cluster.js +++ b/js/server/modules/org/arangodb/cluster.js @@ -533,15 +533,28 @@ function createLocalCollections (plannedCollections) { for (i = 0; i < payload.indexes.length; ++i) { index = payload.indexes[i]; - if (! indexes.hasOwnProperty(index.id)) { + if (index.type !== "primary" && index.type !== "edge" && + ! indexes.hasOwnProperty(index.id)) { console.info("creating index '%s/%s': %s", database, shard, JSON.stringify(index)); - arangodb.db._collection(shard).ensureIndex(index); - payload.DBServer = ourselves; indexes[index.id] = index; + + try { + arangodb.db._collection(shard).ensureIndex(index); + indexes[index.id].error = false; + indexes[index.id].errorNum = 0; + indexes[index.id].errorMessage = ""; + } + catch (err4) { + indexes[index.id].error = true; + indexes[index.id].errorNum = err4.errorNum; + indexes[index.id].errorMessage = err4.errorMessage; + } + + payload.DBServer = ourselves; writeLocked({ part: "Current" }, createCollectionAgency, diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat index 06d34d0eab..ef75bdd3a3 100755 --- a/lib/BasicsC/errors.dat +++ b/lib/BasicsC/errors.dat @@ -112,7 +112,8 @@ ERROR_ARANGO_USE_SYSTEM_DATABASE,1230,"operation only allowed in system database ERROR_ARANGO_ENDPOINT_NOT_FOUND,1231,"endpoint not found","Will be raised when there is an attempt to delete a non-existing endpoint." ERROR_ARANGO_INVALID_KEY_GENERATOR,1232,"invalid key generator","Will be raised when an invalid key generator description is used." ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE,1233,"edge attribute missing","will be raised when the _from or _to values of an edge are undefined or contain an invalid value." -ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING,1234,"index insertion warning - attribute missing in document","Will be raised when an attempt to insert a document into an index is caused by in the document not having one or more attributes which the index is built on" +ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING,1234,"index insertion warning - attribute missing in document","Will be raised when an attempt to insert a document into an index is caused by in the document not having one or more attributes which the index is built on." +ERROR_ARANGO_INDEX_CREATION_FAILED,1235,"index creation failed","Will be raised when an attempt to create an index has failed." ################################################################################ ## ArangoDB storage errors diff --git a/lib/BasicsC/voc-errors.c b/lib/BasicsC/voc-errors.c index 290c64782a..9801aeb6d6 100644 --- a/lib/BasicsC/voc-errors.c +++ b/lib/BasicsC/voc-errors.c @@ -91,6 +91,7 @@ void TRI_InitialiseErrorMessages (void) { REG_ERROR(ERROR_ARANGO_INVALID_KEY_GENERATOR, "invalid key generator"); REG_ERROR(ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE, "edge attribute missing"); REG_ERROR(ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING, "index insertion warning - attribute missing in document"); + REG_ERROR(ERROR_ARANGO_INDEX_CREATION_FAILED, "index creation failed"); REG_ERROR(ERROR_ARANGO_DATAFILE_FULL, "datafile full"); REG_ERROR(ERROR_REPLICATION_NO_RESPONSE, "no response"); REG_ERROR(ERROR_REPLICATION_INVALID_RESPONSE, "invalid response"); diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h index 116adeacfc..d6e9f264e5 100644 --- a/lib/BasicsC/voc-errors.h +++ b/lib/BasicsC/voc-errors.h @@ -192,7 +192,9 @@ extern "C" { /// - 1234: @LIT{index insertion warning - attribute missing in document} /// Will be raised when an attempt to insert a document into an index is /// caused by in the document not having one or more attributes which the -/// index is built on +/// index is built on. +/// - 1235: @LIT{index creation failed} +/// Will be raised when an attempt to create an index has failed. /// - 1300: @LIT{datafile full} /// Will be raised when the datafile reaches its limit. /// - 1400: @LIT{no response} @@ -1310,11 +1312,21 @@ void TRI_InitialiseErrorMessages (void); /// /// Will be raised when an attempt to insert a document into an index is caused /// by in the document not having one or more attributes which the index is -/// built on +/// built on. //////////////////////////////////////////////////////////////////////////////// #define TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING (1234) +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1235: ERROR_ARANGO_INDEX_CREATION_FAILED +/// +/// index creation failed +/// +/// Will be raised when an attempt to create an index has failed. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_ARANGO_INDEX_CREATION_FAILED (1235) + //////////////////////////////////////////////////////////////////////////////// /// @brief 1300: ERROR_ARANGO_DATAFILE_FULL ///