From c93c952c0596e7a952e269f3c6ab4fe386bbd2ab Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Mon, 20 Oct 2014 12:32:08 +0200 Subject: [PATCH] fixed from/to-handling in cluster --- arangod/Aql/AqlValue.cpp | 8 ++++---- arangod/Aql/Collection.cpp | 32 ++++++++++++++++++++++++++++++-- arangod/Aql/ExecutionBlock.cpp | 6 ++++-- arangod/Aql/ExecutionEngine.cpp | 8 ++++++++ arangod/Aql/ExecutionEngine.h | 6 ++++++ arangod/Aql/ExecutionNode.cpp | 7 ++++++- arangod/Cluster/ClusterInfo.h | 19 ++++++++----------- 7 files changed, 66 insertions(+), 20 deletions(-) diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index b609b00bf9..bb0ed729ad 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -494,13 +494,13 @@ Json AqlValue::toJson (triagens::arango::AqlTransaction* trx, if (TRI_IS_EDGE_MARKER(_marker)) { // _from - std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(_marker))); + std::string from(trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_FROM_CID(_marker))); from.push_back('/'); from.append(TRI_EXTRACT_MARKER_FROM_KEY(_marker)); json(TRI_VOC_ATTRIBUTE_FROM, Json(from)); // _to - std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(_marker))); + std::string to(trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(_marker))); to.push_back('/'); to.append(TRI_EXTRACT_MARKER_TO_KEY(_marker)); json(TRI_VOC_ATTRIBUTE_TO, Json(to)); @@ -605,13 +605,13 @@ Json AqlValue::extractArrayMember (triagens::arango::AqlTransaction* trx, return Json(TRI_UNKNOWN_MEM_ZONE, JsonHelper::uint64String(TRI_UNKNOWN_MEM_ZONE, rid)); } else if (strcmp(name, TRI_VOC_ATTRIBUTE_FROM) == 0) { - std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(_marker))); + std::string from(trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_FROM_CID(_marker))); from.push_back('/'); from.append(TRI_EXTRACT_MARKER_FROM_KEY(_marker)); return Json(TRI_UNKNOWN_MEM_ZONE, from); } else if (strcmp(name, TRI_VOC_ATTRIBUTE_TO) == 0) { - std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(_marker))); + std::string to(trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(_marker))); to.push_back('/'); to.append(TRI_EXTRACT_MARKER_TO_KEY(_marker)); return Json(TRI_UNKNOWN_MEM_ZONE, to); diff --git a/arangod/Aql/Collection.cpp b/arangod/Aql/Collection.cpp index 77e8f3b410..0e4fd5861e 100644 --- a/arangod/Aql/Collection.cpp +++ b/arangod/Aql/Collection.cpp @@ -31,6 +31,7 @@ #include "Aql/ExecutionEngine.h" #include "Basics/StringUtils.h" #include "Cluster/ClusterInfo.h" +#include "Cluster/ClusterMethods.h" #include "Utils/Exception.h" #include "VocBase/document-collection.h" #include "VocBase/transaction.h" @@ -80,8 +81,12 @@ Collection::~Collection () { size_t Collection::count () const { if (numDocuments == UNINITIALIZED) { if (ExecutionEngine::isCoordinator()) { - /// TODO: determine the proper number of documents in the coordinator case - numDocuments = 1000; + uint64_t result; + int res = triagens::arango::countOnCoordinator(vocbase->_name, name, result); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_MESSAGE(res, "could not determine number of documents in collection"); + } + numDocuments = static_cast(result); } else { auto document = documentCollection(); @@ -197,6 +202,29 @@ void Collection::fillIndexes () const { } } } + else if (ExecutionEngine::isDBServer()) { + TRI_ASSERT(collection != nullptr); + auto document = documentCollection(); + + // lookup collection in agency by plan id + auto clusterInfo = triagens::arango::ClusterInfo::instance(); + auto collectionInfo = clusterInfo->getCollection(std::string(vocbase->_name), triagens::basics::StringUtils::itoa(document->_info._planId)); + if (collectionInfo.get() == nullptr || (*collectionInfo).empty()) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "collection not found"); + } + + TRI_json_t const* json = (*collectionInfo).getIndexes(); + size_t const n = document->_allIndexes._length; + indexes.reserve(n); + + // register indexes + for (size_t i = 0; i < n; ++i) { + TRI_json_t const* v = TRI_LookupListJson(json, i); + if (v != nullptr) { + indexes.emplace_back(new Index(v)); + } + } + } else { // local collection TRI_ASSERT(collection != nullptr); diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 74fc07fb5f..ee54b62638 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -288,7 +288,7 @@ int ExecutionBlock::resolve (char const* handle, std::string const name(handle, p - handle); cid = _trx->resolver()->getCollectionIdCluster(name); } - + if (cid == 0) { return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND; } @@ -803,6 +803,7 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine, _allBoundsConstant(true) { std::vector> const& orRanges = en->_ranges; + TRI_ASSERT(en->_index != nullptr); TRI_ASSERT(orRanges.size() == 1); // OR expressions not yet implemented @@ -888,7 +889,6 @@ int IndexRangeBlock::initialize () { } bool IndexRangeBlock::readIndex () { - // This is either called from initialize if all bounds are constant, // in this case it is never called again. If there is at least one // variable bound, then readIndex is called once for every item coming @@ -907,6 +907,8 @@ bool IndexRangeBlock::readIndex () { auto en = static_cast(getPlanNode()); IndexOrCondition const* condition = &en->_ranges; + + TRI_ASSERT(en->_index != nullptr); std::unique_ptr newCondition; diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 4dc500edc9..2f64b41e74 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -188,6 +188,14 @@ bool ExecutionEngine::isCoordinator () { return triagens::arango::ServerState::instance()->isCoordinator(); } +//////////////////////////////////////////////////////////////////////////////// +// @brief whether or not we are a db server +//////////////////////////////////////////////////////////////////////////////// + +bool ExecutionEngine::isDBServer () { + return triagens::arango::ServerState::instance()->isDBserver(); +} + // ----------------------------------------------------------------------------- // --SECTION-- walker class for ExecutionNode to instanciate // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/ExecutionEngine.h b/arangod/Aql/ExecutionEngine.h index e0114e28bf..0ec66351d5 100644 --- a/arangod/Aql/ExecutionEngine.h +++ b/arangod/Aql/ExecutionEngine.h @@ -78,6 +78,12 @@ namespace triagens { static bool isCoordinator (); +//////////////////////////////////////////////////////////////////////////////// +// @brief whether or not we are a DB server +//////////////////////////////////////////////////////////////////////////////// + + static bool isDBServer (); + //////////////////////////////////////////////////////////////////////////////// // @brief create an execution engine from a plan //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 16cf4b86db..464a6cf5bd 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -1303,7 +1303,8 @@ IndexRangeNode::IndexRangeNode (ExecutionPlan* plan, _vocbase(plan->getAst()->query()->vocbase()), _collection(plan->getAst()->query()->collections()->get(JsonHelper::checkAndGetStringValue(json.json(), "collection"))), - _outVariable(varFromJson(plan->getAst(), json, "outVariable")), + _outVariable(varFromJson(plan->getAst(), json, "outVariable")), + _index(nullptr), _ranges(), _reverse(false) { @@ -1324,6 +1325,10 @@ IndexRangeNode::IndexRangeNode (ExecutionPlan* plan, _index = _collection->getIndex(iid); _reverse = JsonHelper::checkAndGetBooleanValue(json.json(), "reverse"); + + if (_index == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "index not found"); + } } ExecutionNode::IndexMatch IndexRangeNode::MatchesIndex (IndexMatchVec const& pattern) const { diff --git a/arangod/Cluster/ClusterInfo.h b/arangod/Cluster/ClusterInfo.h index 45b557629e..ee168b7b04 100644 --- a/arangod/Cluster/ClusterInfo.h +++ b/arangod/Cluster/ClusterInfo.h @@ -90,7 +90,7 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// bool empty () const { - return (0 == _json); //|| (id() == 0); + return (nullptr == _json); //|| (id() == 0); } //////////////////////////////////////////////////////////////////////////////// @@ -189,11 +189,11 @@ namespace triagens { TRI_json_t* keyOptions () const { TRI_json_t const* keyOptions = triagens::basics::JsonHelper::getArrayElement(_json, "keyOptions"); - if (keyOptions != 0) { + if (keyOptions != nullptr) { return TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, keyOptions); } - return 0; + return nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -203,7 +203,7 @@ namespace triagens { bool allowUserKeys () const { TRI_json_t const* keyOptions = triagens::basics::JsonHelper::getArrayElement(_json, "keyOptions"); - if (keyOptions != 0) { + if (keyOptions != nullptr) { return triagens::basics::JsonHelper::getBooleanValue(keyOptions, "allowUserKeys", true); } @@ -422,7 +422,7 @@ namespace triagens { TRI_json_t* _json = it->second; b = triagens::basics::JsonHelper::getBooleanValue(_json, name, false); - m.insert(make_pair(it->first,b)); + m.insert(make_pair(it->first, b)); } return m; } @@ -539,15 +539,12 @@ namespace triagens { = triagens::basics::JsonHelper::getArrayElement (_json, "keyOptions"); - if (keyOptions != 0) { + if (keyOptions != nullptr) { return TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, keyOptions); } + } - return 0; - } - else { - return 0; - } + return nullptr; } ////////////////////////////////////////////////////////////////////////////////