diff --git a/UnitTests/Basics/AttributeNameParserTest.cpp b/UnitTests/Basics/AttributeNameParserTest.cpp index 4140f14abe..196a79e1be 100644 --- a/UnitTests/Basics/AttributeNameParserTest.cpp +++ b/UnitTests/Basics/AttributeNameParserTest.cpp @@ -206,6 +206,35 @@ BOOST_AUTO_TEST_CASE (test_nonClosingBracket2) { } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief test_reverseTransform +//////////////////////////////////////////////////////////////////////////////// + +BOOST_AUTO_TEST_CASE (test_reverseTransform) { + std::string input = "foo[*].bar.baz[*]"; + std::vector result; + TRI_ParseAttributeString(input, result); + + std::string output = ""; + TRI_AttributeNamesToString(result, output); + BOOST_CHECK_EQUAL(output, input); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test_reverseTransformToPidPath +//////////////////////////////////////////////////////////////////////////////// + +BOOST_AUTO_TEST_CASE (test_reverseTransformToPidPath) { + std::string input = "foo[*].bar.baz[*]"; + std::string expected = "foo.bar.baz"; + std::vector result; + TRI_ParseAttributeString(input, result); + + std::string output = ""; + TRI_AttributeNamesToString(result, output, true); + BOOST_CHECK_EQUAL(output, expected); +} + diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 1f4322cc7f..6b576d0e37 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -1545,8 +1545,10 @@ void IndexRangeBlock::sortConditions () { for (size_t t = 0; t < numFields; t++) { for (size_t u = 0; u < _condition->at(s).size(); u++) { auto const& ri = _condition->at(s)[u]; + std::string fieldString; + TRI_AttributeNamesToString(en->_index->fields[t], fieldString); - if (en->_index->fields[t].name.compare(ri._attr) == 0) { + if (fieldString.compare(ri._attr) == 0) { TRI_IF_FAILURE("IndexRangeBlock::sortConditionsInner") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 0c7d81571d..af0454d3b3 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -549,20 +549,22 @@ ExecutionNode::IndexMatch ExecutionNode::CompareIndex (ExecutionNode const* node size_t j = 0; for (; (i < idxFields && j < n); i++) { - if (equalityLookupAttributes.find(idx->fields[i].name) != equalityLookupAttributes.end()) { + std::string fieldString; + TRI_AttributeNamesToString(idx->fields[i], fieldString); + if (equalityLookupAttributes.find(fieldString) != equalityLookupAttributes.end()) { // found an attribute in the sort criterion that is used in an equality lookup, too... // (e.g. doc.value == 1 && SORT doc.value1) // in this case, we can ignore the sorting for this particular attribute, as the index // will only return constant values for it match.matches.push_back(FORWARD_MATCH); // doesn't matter here if FORWARD or BACKWARD ++interestingCount; - if (attrs[j].first == idx->fields[i].name) { + if (attrs[j].first == fieldString) { ++j; } continue; } - if (attrs[j].first == idx->fields[i].name) { + if (attrs[j].first == fieldString) { if (attrs[j].second) { // ascending match.matches.push_back(FORWARD_MATCH); @@ -1246,7 +1248,9 @@ size_t EnumerateCollectionNode::getUsableFieldsOfIndex (Index const* idx, std::unordered_set const& attrs) const { size_t count = 0; for (size_t i = 0; i < idx->fields.size(); i++) { - if (attrs.find(idx->fields[i].name) == attrs.end()) { + std::string tmp; + TRI_AttributeNamesToString(idx->fields[i], tmp); + if (attrs.find(tmp) == attrs.end()) { break; } diff --git a/arangod/Aql/Index.h b/arangod/Aql/Index.h index ac7083ebd0..1c6e80d912 100644 --- a/arangod/Aql/Index.h +++ b/arangod/Aql/Index.h @@ -97,7 +97,9 @@ namespace triagens { auto * name = static_cast(TRI_AtVector(&f->_value._objects, i)); if (TRI_IsStringJson(name)) { - fields.emplace_back(std::string(name->_value._string.data, name->_value._string.length - 1), false); + std::vector parsedAttributes; + TRI_ParseAttributeString(std::string(name->_value._string.data, name->_value._string.length - 1), parsedAttributes); + fields.emplace_back(parsedAttributes); } } } @@ -123,7 +125,9 @@ namespace triagens { triagens::basics::Json f(triagens::basics::Json::Array); for (auto const& field : fields) { - f.add(triagens::basics::Json(field.name)); + std::string tmp; + TRI_AttributeNamesToString(field, tmp); + f.add(triagens::basics::Json(tmp)); } json("fields", f); @@ -168,11 +172,11 @@ namespace triagens { public: - TRI_idx_iid_t const id; - triagens::arango::Index::IndexType type; - bool unique; - bool sparse; - std::vector fields; + TRI_idx_iid_t const id; + triagens::arango::Index::IndexType type; + bool unique; + bool sparse; + std::vector> fields; private: diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 16214f20c5..3a78a66e75 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -2364,7 +2364,9 @@ class FilterToEnumCollFinder final : public WalkerWorker { auto const map = _rangeInfoMapVec->find(var->name, validPos[k]); for (size_t j = 0; j < idx->fields.size(); j++) { - auto range = map->find(idx->fields[j].name); + std::string fieldString; + TRI_AttributeNamesToString(idx->fields[j], fieldString); + auto range = map->find(fieldString); if (range == map->end() || ! range->second.is1ValueRangeInfo()) { indexOrCondition.clear(); // not usable @@ -2408,8 +2410,10 @@ class FilterToEnumCollFinder final : public WalkerWorker { for (size_t k = 0; k < validPos.size(); k++) { auto const map = _rangeInfoMapVec->find(var->name, validPos[k]); + std::string fieldString; + TRI_AttributeNamesToString(idx->fields[0], fieldString); // check if there is a range that contains the first index attribute - auto range = map->find(idx->fields[0].name); + auto range = map->find(fieldString); if (range == map->end()) { indexOrCondition.clear(); @@ -2424,7 +2428,9 @@ class FilterToEnumCollFinder final : public WalkerWorker { bool handled = false; size_t j = 0; while (++j < prefixes.at(i) && equality) { - range = map->find(idx->fields[j].name); + std::string fieldString; + TRI_AttributeNamesToString(idx->fields[j], fieldString); + range = map->find(fieldString); if (range == map->end()) { indexOrCondition.clear(); @@ -2452,7 +2458,9 @@ class FilterToEnumCollFinder final : public WalkerWorker { auto const map = _rangeInfoMapVec->find(var->name, validPos[k]); for (size_t j = 0; j < idx->fields.size(); j++) { - auto range = map->find(idx->fields[j].name); + std::string fieldString; + TRI_AttributeNamesToString(idx->fields[j], fieldString); + auto range = map->find(fieldString); if (range == map->end()) { indexOrCondition.clear(); diff --git a/arangod/Indexes/CapConstraint.cpp b/arangod/Indexes/CapConstraint.cpp index e9fed079cf..301f365923 100644 --- a/arangod/Indexes/CapConstraint.cpp +++ b/arangod/Indexes/CapConstraint.cpp @@ -52,7 +52,7 @@ CapConstraint::CapConstraint (TRI_idx_iid_t iid, TRI_document_collection_t* collection, size_t count, int64_t size) - : Index(iid, collection, std::vector()), + : Index(iid, collection, std::vector>()), _count(count), _size(static_cast(size)) { diff --git a/arangod/Indexes/EdgeIndex.cpp b/arangod/Indexes/EdgeIndex.cpp index faec8e67e4..5bf47e9e11 100644 --- a/arangod/Indexes/EdgeIndex.cpp +++ b/arangod/Indexes/EdgeIndex.cpp @@ -315,7 +315,7 @@ static bool IsEqualElementEdgeToByKey (void const* left, EdgeIndex::EdgeIndex (TRI_idx_iid_t iid, TRI_document_collection_t* collection) - : Index(iid, collection, std::vector({ { TRI_VOC_ATTRIBUTE_FROM, false }, { TRI_VOC_ATTRIBUTE_TO , false } })), + : Index(iid, collection, std::vector>({ { { TRI_VOC_ATTRIBUTE_FROM, false } }, { { TRI_VOC_ATTRIBUTE_TO , false } } })), _edgesFrom(nullptr), _edgesTo(nullptr) { diff --git a/arangod/Indexes/FulltextIndex.cpp b/arangod/Indexes/FulltextIndex.cpp index c3e8edb998..2993f9190f 100644 --- a/arangod/Indexes/FulltextIndex.cpp +++ b/arangod/Indexes/FulltextIndex.cpp @@ -121,7 +121,7 @@ FulltextIndex::FulltextIndex (TRI_idx_iid_t iid, TRI_document_collection_t* collection, std::string const& attribute, int minWordLength) - : Index(iid, collection, std::vector{ { attribute, false } } ), + : Index(iid, collection, std::vector> { { { attribute, false } } } ), _pid(0), _fulltextIndex(nullptr), _minWordLength(minWordLength > 0 ? minWordLength : 1) { diff --git a/arangod/Indexes/FulltextIndex.h b/arangod/Indexes/FulltextIndex.h index 80b0583cdd..8b29d698bc 100644 --- a/arangod/Indexes/FulltextIndex.h +++ b/arangod/Indexes/FulltextIndex.h @@ -92,7 +92,9 @@ namespace triagens { int cleanup () override final; bool isSame (std::string const& field, int minWordLength) const { - return (_minWordLength == minWordLength && fields()[0].name == field); + std::string fieldString; + TRI_AttributeNamesToString(fields()[0], fieldString); + return (_minWordLength == minWordLength && fieldString == field); } TRI_fts_index_t* internals () { diff --git a/arangod/Indexes/GeoIndex2.cpp b/arangod/Indexes/GeoIndex2.cpp index d7d9f2a4a3..83a0a23ecc 100644 --- a/arangod/Indexes/GeoIndex2.cpp +++ b/arangod/Indexes/GeoIndex2.cpp @@ -49,7 +49,7 @@ using namespace triagens::arango; GeoIndex2::GeoIndex2 (TRI_idx_iid_t iid, TRI_document_collection_t* collection, - std::vector const& fields, + std::vector> const& fields, std::vector const& paths, bool geoJson) : Index(iid, collection, fields), @@ -76,7 +76,7 @@ GeoIndex2::GeoIndex2 (TRI_idx_iid_t iid, GeoIndex2::GeoIndex2 (TRI_idx_iid_t iid, TRI_document_collection_t* collection, - std::vector const& fields, + std::vector> const& fields, std::vector const& paths) : Index(iid, collection, fields), _paths(paths), diff --git a/arangod/Indexes/GeoIndex2.h b/arangod/Indexes/GeoIndex2.h index 25befa7b98..1accef5ab5 100644 --- a/arangod/Indexes/GeoIndex2.h +++ b/arangod/Indexes/GeoIndex2.h @@ -58,13 +58,13 @@ namespace triagens { GeoIndex2 (TRI_idx_iid_t, struct TRI_document_collection_t*, - std::vector const&, + std::vector> const&, std::vector const&, bool); GeoIndex2 (TRI_idx_iid_t, struct TRI_document_collection_t*, - std::vector const&, + std::vector> const&, std::vector const&); ~GeoIndex2 (); diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index dddcd527ed..eb584ff3cb 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -250,7 +250,7 @@ static int HashIndex_find (TRI_hash_array_t const* hashArray, HashIndex::HashIndex (TRI_idx_iid_t iid, TRI_document_collection_t* collection, - std::vector const& fields, + std::vector> const& fields, std::vector const& paths, bool unique, bool sparse) diff --git a/arangod/Indexes/HashIndex.h b/arangod/Indexes/HashIndex.h index d199fffff5..a1162b7078 100644 --- a/arangod/Indexes/HashIndex.h +++ b/arangod/Indexes/HashIndex.h @@ -57,7 +57,7 @@ namespace triagens { HashIndex (TRI_idx_iid_t, struct TRI_document_collection_t*, - std::vector const&, + std::vector> const&, std::vector const&, bool, bool); diff --git a/arangod/Indexes/Index.cpp b/arangod/Indexes/Index.cpp index bfa10d7e84..21334bf5f8 100644 --- a/arangod/Indexes/Index.cpp +++ b/arangod/Indexes/Index.cpp @@ -45,7 +45,7 @@ using namespace triagens::arango; Index::Index (TRI_idx_iid_t iid, TRI_document_collection_t* collection, - std::vector const& fields) + std::vector> const& fields) : _iid(iid), _collection(collection), _fields(fields) { @@ -340,7 +340,9 @@ triagens::basics::Json Index::toJson (TRI_memory_zone_t* zone) const { triagens::basics::Json f(zone, triagens::basics::Json::Array, fields().size()); for (auto const& field : fields()) { - f.add(triagens::basics::Json(zone, field.name)); + std::string fieldString; + TRI_AttributeNamesToString(field, fieldString); + f.add(triagens::basics::Json(zone, fieldString)); } json("fields", f); diff --git a/arangod/Indexes/Index.h b/arangod/Indexes/Index.h index 61777365a6..45384c9590 100644 --- a/arangod/Indexes/Index.h +++ b/arangod/Indexes/Index.h @@ -76,7 +76,7 @@ namespace triagens { Index (TRI_idx_iid_t, struct TRI_document_collection_t*, - std::vector const&); + std::vector >const&); virtual ~Index (); @@ -118,7 +118,7 @@ namespace triagens { /// @brief return the index fields //////////////////////////////////////////////////////////////////////////////// - inline std::vector const& fields () const { + inline std::vector> const& fields () const { return _fields; } @@ -204,11 +204,11 @@ namespace triagens { protected: - TRI_idx_iid_t const _iid; + TRI_idx_iid_t const _iid; - struct TRI_document_collection_t* _collection; + struct TRI_document_collection_t* _collection; - std::vector const _fields; + std::vector> const _fields; }; diff --git a/arangod/Indexes/PrimaryIndex.cpp b/arangod/Indexes/PrimaryIndex.cpp index 5503880a5b..9abe276d6b 100644 --- a/arangod/Indexes/PrimaryIndex.cpp +++ b/arangod/Indexes/PrimaryIndex.cpp @@ -73,7 +73,7 @@ uint64_t const PrimaryIndex::InitialSize = 251; // ----------------------------------------------------------------------------- PrimaryIndex::PrimaryIndex (TRI_document_collection_t* collection) - : Index(0, collection, std::vector( { { TRI_VOC_ATTRIBUTE_KEY, false } } )) { + : Index(0, collection, std::vector>( { { { TRI_VOC_ATTRIBUTE_KEY, false } } } )) { _primaryIndex._nrAlloc = 0; _primaryIndex._nrUsed = 0; diff --git a/arangod/Indexes/SkiplistIndex2.cpp b/arangod/Indexes/SkiplistIndex2.cpp index e04ab4fd62..0f8525aa09 100644 --- a/arangod/Indexes/SkiplistIndex2.cpp +++ b/arangod/Indexes/SkiplistIndex2.cpp @@ -127,7 +127,7 @@ static int FillLookupOperator (TRI_index_operator_t* slOperator, SkiplistIndex2::SkiplistIndex2 (TRI_idx_iid_t iid, TRI_document_collection_t* collection, - std::vector const& fields, + std::vector> const& fields, std::vector const& paths, bool unique, bool sparse) diff --git a/arangod/Indexes/SkiplistIndex2.h b/arangod/Indexes/SkiplistIndex2.h index aa0f04a3ad..e3c8a93056 100644 --- a/arangod/Indexes/SkiplistIndex2.h +++ b/arangod/Indexes/SkiplistIndex2.h @@ -57,7 +57,7 @@ namespace triagens { SkiplistIndex2 (TRI_idx_iid_t, struct TRI_document_collection_t*, - std::vector const&, + std::vector> const&, std::vector const&, bool, bool); diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 9e9896347f..ccf57cec13 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -183,7 +183,7 @@ static void CalculateSkipLimitSlice (size_t length, //////////////////////////////////////////////////////////////////////////////// static TRI_index_operator_t* SetupConditionsSkiplist (v8::Isolate* isolate, - std::vector const& fields, + std::vector> const& fields, VocShaper* shaper, v8::Handle conditions) { TRI_index_operator_t* lastOperator = nullptr; @@ -199,7 +199,9 @@ static TRI_index_operator_t* SetupConditionsSkiplist (v8::Isolate* isolate, // iterate over all index fields size_t i = 0; for (auto const& field : fields) { - v8::Handle key = TRI_V8_STD_STRING(field.name); + std::string fieldString; + TRI_AttributeNamesToString(field, fieldString); + v8::Handle key = TRI_V8_STD_STRING(fieldString); if (! conditions->HasOwnProperty(key)) { break; @@ -394,7 +396,7 @@ MEM_ERROR: //////////////////////////////////////////////////////////////////////////////// static TRI_index_operator_t* SetupExampleSkiplist (v8::Isolate* isolate, - std::vector const& fields, + std::vector> const& fields, VocShaper* shaper, v8::Handle example) { TRI_json_t* parameters = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE); @@ -404,7 +406,9 @@ static TRI_index_operator_t* SetupExampleSkiplist (v8::Isolate* isolate, } for (auto const& field : fields) { - v8::Handle key = TRI_V8_STD_STRING(field.name); + std::string fieldString; + TRI_AttributeNamesToString(field, fieldString); + v8::Handle key = TRI_V8_STD_STRING(fieldString); if (! example->HasOwnProperty(key)) { break; diff --git a/arangod/VocBase/document-collection.cpp b/arangod/VocBase/document-collection.cpp index b200309000..ea6a50ac9f 100644 --- a/arangod/VocBase/document-collection.cpp +++ b/arangod/VocBase/document-collection.cpp @@ -3371,7 +3371,7 @@ static int FillIndex (TRI_document_collection_t* document, //////////////////////////////////////////////////////////////////////////////// static triagens::arango::Index* LookupPathIndexDocumentCollection (TRI_document_collection_t* collection, - std::vector const& paths, + std::vector> const& paths, triagens::arango::Index::IndexType type, int sparsity, bool unique, @@ -3434,11 +3434,16 @@ static triagens::arango::Index* LookupPathIndexDocumentCollection (TRI_document_ // any permutation of attributes is allowed for (size_t i = 0; i < n; ++i) { found = false; + size_t fieldSize = idxFields[i].size(); for (size_t j = 0; j < n; ++j) { - if (idxFields[i] == paths[j]) { - found = true; - break; + if (fieldSize == paths[j].size()) { + for (size_t k = 0; k < fieldSize; ++k) { + if (idxFields[j][k] == paths[j][k]) { + found = true; + break; + } + } } } @@ -3450,9 +3455,14 @@ static triagens::arango::Index* LookupPathIndexDocumentCollection (TRI_document_ else { // attributes need to be present in a given order for (size_t i = 0; i < n; ++i) { - if (idxFields[i] != paths[i]) { - found = false; - break; + size_t fieldSize = idxFields[i].size(); + if (fieldSize == paths[i].size()) { + for (size_t k = 0; k < fieldSize; ++k) { + if (idxFields[i][k] != paths[i][k]) { + found = false; + break; + } + } } } } @@ -3742,7 +3752,7 @@ bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document, static int PidNamesByAttributeNames (std::vector const& attributes, VocShaper* shaper, std::vector& pids, - std::vector& names, + std::vector>& names, bool sorted, bool create) { pids.reserve(attributes.size()); @@ -3754,25 +3764,31 @@ static int PidNamesByAttributeNames (std::vector const& attributes, if (sorted) { // combine name and pid - typedef std::pair PidNameType; + typedef std::pair, TRI_shape_pid_t> PidNameType; std::vector pidNames; pidNames.reserve(attributes.size()); for (auto const& name : attributes) { + std::vector attrNameList; + TRI_ParseAttributeString(name, attrNameList); + TRI_ASSERT(attrNameList.size() > 0); + std::string pidPath; + TRI_AttributeNamesToString(attrNameList, pidPath, true); + TRI_shape_pid_t pid; if (create) { - pid = shaper->findOrCreateAttributePathByName(name.c_str()); + pid = shaper->findOrCreateAttributePathByName(pidPath.c_str()); } else { - pid = shaper->lookupAttributePathByName(name.c_str()); + pid = shaper->lookupAttributePathByName(pidPath.c_str()); } if (pid == 0) { return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); } - pidNames.emplace_back(std::make_pair(name, pid)); + pidNames.emplace_back(std::make_pair(attrNameList, pid)); } // sort according to pid @@ -3782,7 +3798,7 @@ static int PidNamesByAttributeNames (std::vector const& attributes, for (auto const& it : pidNames) { pids.emplace_back(it.second); - names.emplace_back(it.first, false); + names.emplace_back(it.first); } } @@ -3792,13 +3808,20 @@ static int PidNamesByAttributeNames (std::vector const& attributes, else { for (auto const& name : attributes) { + + std::vector attrNameList; + TRI_ParseAttributeString(name, attrNameList); + TRI_ASSERT(attrNameList.size() > 0); + std::string pidPath; + TRI_AttributeNamesToString(attrNameList, pidPath, true); + TRI_shape_pid_t pid; if (create) { - pid = shaper->findOrCreateAttributePathByName(name.c_str()); + pid = shaper->findOrCreateAttributePathByName(pidPath.c_str()); } else { - pid = shaper->lookupAttributePathByName(name.c_str()); + pid = shaper->lookupAttributePathByName(pidPath.c_str()); } if (pid == 0) { @@ -3806,7 +3829,7 @@ static int PidNamesByAttributeNames (std::vector const& attributes, } pids.emplace_back(pid); - names.emplace_back(name, false); + names.emplace_back(attrNameList); } } @@ -4062,14 +4085,14 @@ static triagens::arango::Index* CreateGeoIndexDocumentCollection (TRI_document_c // create a new index if (! location.empty()) { - geoIndex.reset(new triagens::arango::GeoIndex2(iid, document, std::vector{ { location, false } }, std::vector{ loc }, geoJson)); + geoIndex.reset(new triagens::arango::GeoIndex2(iid, document, std::vector> { { { location, false } } }, std::vector{ loc }, geoJson)); LOG_TRACE("created geo-index for location '%s': %ld", location.c_str(), (unsigned long) loc); } else if (! longitude.empty() && ! latitude.empty()) { - geoIndex.reset(new triagens::arango::GeoIndex2(iid, document, std::vector{ { latitude, false } , { longitude, false } }, std::vector{ lat, lon })); + geoIndex.reset(new triagens::arango::GeoIndex2(iid, document, std::vector>{ { { latitude, false } } , { { longitude, false } } }, std::vector{ lat, lon })); LOG_TRACE("created geo-index for location '%s': %ld, %ld", location.c_str(), @@ -4354,7 +4377,7 @@ static triagens::arango::Index* CreateHashIndexDocumentCollection (TRI_document_ bool unique, bool* created) { std::vector paths; - std::vector fields; + std::vector> fields; // determine the sorted shape ids for the attributes int res = PidNamesByAttributeNames(attributes, @@ -4453,7 +4476,7 @@ triagens::arango::Index* TRI_LookupHashIndexDocumentCollection (TRI_document_col int sparsity, bool unique) { std::vector paths; - std::vector fields; + std::vector> fields; // determine the sorted shape ids for the attributes int res = PidNamesByAttributeNames(attributes, @@ -4521,7 +4544,7 @@ static triagens::arango::Index* CreateSkiplistIndexDocumentCollection (TRI_docum bool unique, bool* created) { std::vector paths; - std::vector fields; + std::vector> fields; int res = PidNamesByAttributeNames(attributes, document->getShaper(), // ONLY IN INDEX, PROTECTED by RUNTIME @@ -4617,7 +4640,7 @@ triagens::arango::Index* TRI_LookupSkiplistIndexDocumentCollection (TRI_document int sparsity, bool unique) { std::vector paths; - std::vector fields; + std::vector> fields; // determine the unsorted shape ids for the attributes int res = PidNamesByAttributeNames(attributes, diff --git a/lib/Basics/AttributeNameParser.cpp b/lib/Basics/AttributeNameParser.cpp index 0d2263d3f2..d5c63dbf13 100644 --- a/lib/Basics/AttributeNameParser.cpp +++ b/lib/Basics/AttributeNameParser.cpp @@ -60,3 +60,25 @@ void triagens::basics::TRI_ParseAttributeString ( result.emplace_back(input.substr(parsedUntil), false); } } + +void triagens::basics::TRI_AttributeNamesToString ( + std::vector const& input, + std::string& result, + bool excludeExpansion + ) { + TRI_ASSERT(result.size() == 0); + bool isFirst = true; + for (auto& it : input) { + if (!isFirst) { + result += "."; + } + isFirst = false; + result += it.name; + if (! excludeExpansion && it.shouldExpand) { + result += "[*]"; + } + } +} + + + diff --git a/lib/Basics/AttributeNameParser.h b/lib/Basics/AttributeNameParser.h index 5d32ae581d..d02f490eab 100644 --- a/lib/Basics/AttributeNameParser.h +++ b/lib/Basics/AttributeNameParser.h @@ -64,10 +64,32 @@ namespace triagens { } }; + + + +// ----------------------------------------------------------------------------- +// --SECTION-- public functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Parse an input string into attribute names and expansion flags +//////////////////////////////////////////////////////////////////////////////// + void TRI_ParseAttributeString ( std::string const& input, std::vector& result ); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transform a vector of AttributeNames back into a string +//////////////////////////////////////////////////////////////////////////////// + + void TRI_AttributeNamesToString ( + std::vector const& input, + std::string& result, + bool excludeExpansion = false + ); + } }