From 9472eb7b455e0597f09fb08bd654818a68e9fb4e Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Fri, 25 Sep 2015 16:30:29 +0200 Subject: [PATCH] make it link again --- arangod/Aql/ConditionFinder.cpp | 1 + arangod/Aql/ExecutionEngine.cpp | 1 + arangod/Aql/ExecutionNode.cpp | 125 +++++++++++++++++++++++++++++++- arangod/Aql/ExecutionPlan.cpp | 1 + arangod/Aql/OptimizerRules.cpp | 14 ++++ 5 files changed, 140 insertions(+), 2 deletions(-) diff --git a/arangod/Aql/ConditionFinder.cpp b/arangod/Aql/ConditionFinder.cpp index bb92e24c19..ac74f5b839 100644 --- a/arangod/Aql/ConditionFinder.cpp +++ b/arangod/Aql/ConditionFinder.cpp @@ -47,6 +47,7 @@ bool ConditionFinder::before (ExecutionNode* en) { case EN::REMOTE: case EN::SUBQUERY: case EN::SORT: + case EN::INDEX: case EN::INDEX_RANGE: // in these cases we simply ignore the intermediate nodes, note // that we have taken care of nodes that could throw exceptions diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 5874fe67b4..578bb97c60 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -67,6 +67,7 @@ static ExecutionBlock* CreateBlock (ExecutionEngine* engine, case ExecutionNode::INDEX_RANGE: { return new IndexRangeBlock(engine, static_cast(en)); } + // TODO FIXME add INDEX case ExecutionNode::ENUMERATE_COLLECTION: { return new EnumerateCollectionBlock(engine, static_cast(en)); diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 7735d15cde..c1d75ee5e8 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -60,6 +60,7 @@ std::unordered_map const ExecutionNode::TypeNames{ { static_cast(SINGLETON), "SingletonNode" }, { static_cast(ENUMERATE_COLLECTION), "EnumerateCollectionNode" }, { static_cast(ENUMERATE_LIST), "EnumerateListNode" }, + { static_cast(INDEX), "IndexNode" }, { static_cast(INDEX_RANGE), "IndexRangeNode" }, { static_cast(LIMIT), "LimitNode" }, { static_cast(CALCULATION), "CalculationNode" }, @@ -230,6 +231,8 @@ ExecutionNode* ExecutionNode::fromJsonFactory (ExecutionPlan* plan, return new NoResultsNode(plan, oneNode); case INDEX_RANGE: return new IndexRangeNode(plan, oneNode); + case INDEX: + return new IndexNode(plan, oneNode); case REMOTE: return new RemoteNode(plan, oneNode); case GATHER: { @@ -912,7 +915,8 @@ ExecutionNode::RegisterPlan* ExecutionNode::RegisterPlan::clone (ExecutionPlan* void ExecutionNode::RegisterPlan::after (ExecutionNode *en) { switch (en->getType()) { case ExecutionNode::ENUMERATE_COLLECTION: - case ExecutionNode::INDEX_RANGE: { + case ExecutionNode::INDEX_RANGE: + case ExecutionNode::INDEX: { depth++; nrRegsHere.emplace_back(1); // create a copy of the last value here @@ -926,7 +930,7 @@ void ExecutionNode::RegisterPlan::after (ExecutionNode *en) { totalNrRegs++; break; } - + case ExecutionNode::ENUMERATE_LIST: { depth++; nrRegsHere.emplace_back(1); @@ -1480,6 +1484,122 @@ double EnumerateListNode::estimateCost (size_t& nrItems) const { return depCost + static_cast(length) * incoming; } +// ----------------------------------------------------------------------------- +// --SECTION-- methods of IndexNode +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief toJson, for IndexNode - TODO +//////////////////////////////////////////////////////////////////////////////// + +void IndexNode::toJsonHelper (triagens::basics::Json& nodes, + TRI_memory_zone_t* zone, + bool verbose) const { + triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric(nodes, zone, verbose)); + // call base class method + + if (json.isEmpty()) { + return; + } + + // Now put info about vocbase and cid in there + json("database", triagens::basics::Json(_vocbase->_name)) + ("collection", triagens::basics::Json(_collection->getName())) + ("outVariable", _outVariable->toJson()); + +// json("index", _index->toJson()); + json("reverse", triagens::basics::Json(_reverse)); + + // And add it: + nodes(json); +} + +ExecutionNode* IndexNode::clone (ExecutionPlan* plan, + bool withDependencies, + bool withProperties) const { + auto outVariable = _outVariable; + + if (withProperties) { + outVariable = plan->getAst()->variables()->createVariable(outVariable); + } + + // TODO FIXME + auto c = new IndexNode(plan, _id, _vocbase, _collection, + outVariable, _indexes, _condition, _reverse); + + cloneHelper(c, plan, withDependencies, withProperties); + + return static_cast(c); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor for IndexNode from Json - TODO +//////////////////////////////////////////////////////////////////////////////// + +IndexNode::IndexNode (ExecutionPlan* plan, + triagens::basics::Json const& json) + : ExecutionNode(plan, json), + _vocbase(plan->getAst()->query()->vocbase()), + _collection(plan->getAst()->query()->collections()->get(JsonHelper::checkAndGetStringValue(json.json(), "collection"))), + _outVariable(varFromJson(plan->getAst(), json, "outVariable")), + _indexes(), + _condition(nullptr), + _reverse(false) { + + // TODO FIXME +/* + // now the index . . . + // TODO the following could be a constructor method for + // an Index object when these are actually used + auto index = JsonHelper::checkAndGetObjectValue(json.json(), "index"); + auto iid = JsonHelper::checkAndGetStringValue(index, "id"); + + _index = _collection->getIndex(iid); +*/ + _reverse = JsonHelper::checkAndGetBooleanValue(json.json(), "reverse"); + +// if (_index == nullptr) { +// THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "index not found"); +// } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an index range node is a multiple of the cost of +/// its unique dependency - TODO +//////////////////////////////////////////////////////////////////////////////// + +double IndexNode::estimateCost (size_t& nrItems) const { + nrItems = 1; // TODO FIXME + return 1.0; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief getVariablesUsedHere, returning a vector +//////////////////////////////////////////////////////////////////////////////// + +std::vector IndexNode::getVariablesUsedHere () const { + std::unordered_set s; + // actual work is done by that method + getVariablesUsedHere(s); + + // copy result into vector + std::vector v; + v.reserve(s.size()); + + for (auto const& vv : s) { + v.emplace_back(const_cast(vv)); + } + return v; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief getVariablesUsedHere, modifying the set in-place - TODO +//////////////////////////////////////////////////////////////////////////////// + +void IndexNode::getVariablesUsedHere (std::unordered_set& vars) const { + // TODO FIXME +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of IndexRangeNode // ----------------------------------------------------------------------------- @@ -2499,6 +2619,7 @@ struct UserVarFinder final : public WalkerWorker { depth = 0; } else if (en->getType() == ExecutionNode::ENUMERATE_COLLECTION || + en->getType() == ExecutionNode::INDEX || en->getType() == ExecutionNode::INDEX_RANGE || en->getType() == ExecutionNode::ENUMERATE_LIST || en->getType() == ExecutionNode::AGGREGATE) { diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index 9f9e895140..025c4ab4d1 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -1836,6 +1836,7 @@ bool ExecutionPlan::isDeadSimple () const { if (nodeType == ExecutionNode::SUBQUERY || nodeType == ExecutionNode::ENUMERATE_COLLECTION || nodeType == ExecutionNode::ENUMERATE_LIST || + nodeType == ExecutionNode::INDEX || nodeType == ExecutionNode::INDEX_RANGE) { // these node types are not simple return false; diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 7de52bc752..0cd45f687c 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -846,6 +846,7 @@ int triagens::aql::removeSortRandRule (Optimizer* opt, case EN::FILTER: case EN::SUBQUERY: case EN::ENUMERATE_LIST: + case EN::INDEX: // TODO FIXME case EN::INDEX_RANGE: { // if we found another SortNode, an AggregateNode, FilterNode, a SubqueryNode, // an EnumerateListNode or an IndexRangeNode @@ -1046,6 +1047,7 @@ int triagens::aql::moveCalculationsDownRule (Optimizer* opt, shouldMove = true; } else if (currentType == EN::INDEX_RANGE || + currentType == EN::INDEX || currentType == EN::ENUMERATE_COLLECTION || currentType == EN::ENUMERATE_LIST || currentType == EN::AGGREGATE || @@ -2125,6 +2127,7 @@ class FilterToEnumCollFinder final : public WalkerWorker { case EN::SUBQUERY: case EN::SORT: case EN::INDEX_RANGE: + case EN::INDEX: break; case EN::CALCULATION: { @@ -2966,6 +2969,7 @@ class SortToIndexNode final : public WalkerWorker { if (node->getType() == EN::ENUMERATE_COLLECTION || node->getType() == EN::INDEX_RANGE || + node->getType() == EN::INDEX || node->getType() == EN::ENUMERATE_LIST) { // we are contained in an outer loop return true; @@ -3095,6 +3099,7 @@ class SortToIndexNode final : public WalkerWorker { case EN::REMOTE: case EN::ILLEGAL: case EN::LIMIT: // LIMIT is criterion to stop + case EN::INDEX: // TODO FIXME return true; // abort. case EN::SORT: // pulling two sorts together is done elsewhere. @@ -3561,6 +3566,7 @@ int triagens::aql::scatterInClusterRule (Optimizer* opt, std::vector const types = { ExecutionNode::ENUMERATE_COLLECTION, ExecutionNode::INDEX_RANGE, + ExecutionNode::INDEX, ExecutionNode::INSERT, ExecutionNode::UPDATE, ExecutionNode::REPLACE, @@ -3597,6 +3603,10 @@ int triagens::aql::scatterInClusterRule (Optimizer* opt, vocbase = static_cast(node)->vocbase(); collection = static_cast(node)->collection(); } + else if (nodeType == ExecutionNode::INDEX) { + vocbase = static_cast(node)->vocbase(); + collection = static_cast(node)->collection(); + } else if (nodeType == ExecutionNode::INSERT || nodeType == ExecutionNode::UPDATE || nodeType == ExecutionNode::REPLACE || @@ -3921,6 +3931,7 @@ int triagens::aql::distributeFilternCalcToClusterRule (Optimizer* opt, case EN::REMOTE: case EN::LIMIT: case EN::SORT: + case EN::INDEX: case EN::INDEX_RANGE: case EN::ENUMERATE_COLLECTION: //do break @@ -4018,6 +4029,7 @@ int triagens::aql::distributeSortToClusterRule (Optimizer* opt, case EN::REMOTE: case EN::LIMIT: case EN::INDEX_RANGE: + case EN::INDEX: case EN::ENUMERATE_COLLECTION: // For all these, we do not want to pull a SortNode further down // out to the DBservers, note that potential FilterNodes and @@ -4291,6 +4303,7 @@ class RemoveToEnumCollFinder final : public WalkerWorker { case EN::ILLEGAL: case EN::LIMIT: case EN::SORT: + case EN::INDEX: case EN::INDEX_RANGE: { // if we meet any of the above, then we abort . . . } @@ -4832,6 +4845,7 @@ int triagens::aql::patchUpdateStatementsRule (Optimizer* opt, auto const type = dep->getType(); if (type == EN::ENUMERATE_LIST || + type == EN::INDEX || type == EN::INDEX_RANGE || type == EN::SUBQUERY) { // not suitable