diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index fe2e1aa350..05929748d4 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -680,6 +680,16 @@ std::string const& AstNode::getValueTypeString () const { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_NOT_IMPLEMENTED, "missing node type in ValueTypeNames"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief stringify the AstNode +//////////////////////////////////////////////////////////////////////////////// + +std::string AstNode::toString (AstNode const* node) { + std::unique_ptr json(node->toJson(TRI_UNKNOWN_MEM_ZONE, false)); + + return triagens::basics::JsonHelper::toString(json.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief checks whether we know a type of this kind; throws exception if not. //////////////////////////////////////////////////////////////////////////////// @@ -2033,6 +2043,31 @@ void AstNode::appendValue (triagens::basics::StringBuffer* buffer) const { } } +// ----------------------------------------------------------------------------- +// --SECTION-- public non-member functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the AstNode to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<< (std::ostream& stream, + triagens::aql::AstNode const* node) { + stream << triagens::aql::AstNode::toString(node); + return stream; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the AstNode to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<< (std::ostream& stream, + triagens::aql::AstNode const& node) { + stream << triagens::aql::AstNode::toString(&node); + return stream; +} + + // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index dc631b4dc3..6689ebad56 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -281,14 +281,20 @@ namespace triagens { std::string const& getValueTypeString () const; //////////////////////////////////////////////////////////////////////////////// -/// @brief checks whether we know a type of this kind; throws exception if not. +/// @brief stringify the AstNode +//////////////////////////////////////////////////////////////////////////////// + + static std::string toString (AstNode const*); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief checks whether we know a type of this kind; throws exception if not //////////////////////////////////////////////////////////////////////////////// static void validateType (int type); //////////////////////////////////////////////////////////////////////////////// /// @brief checks whether we know a value type of this kind; -/// throws exception if not. +/// throws exception if not //////////////////////////////////////////////////////////////////////////////// static void validateValueType (int type); @@ -890,6 +896,13 @@ namespace triagens { } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the AstNode to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<< (std::ostream&, triagens::aql::AstNode const*); +std::ostream& operator<< (std::ostream&, triagens::aql::AstNode const&); + #endif // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/Condition.cpp b/arangod/Aql/Condition.cpp index de0bb34fa7..2034149dc6 100644 --- a/arangod/Aql/Condition.cpp +++ b/arangod/Aql/Condition.cpp @@ -268,7 +268,7 @@ bool Condition::findIndexForAndNode (AstNode const* node, // This code is never responsible for the content of this pointer. Index const* bestIndex = nullptr; - double bestCost = MaxFilterCost + MaxSortCost + std::numeric_limits::epsilon(); + double bestCost = MaxFilterCost + MaxSortCost + std::numeric_limits::epsilon(); std::vector indexes = colNode->collection()->getIndexes(); diff --git a/arangod/Aql/IndexNode.cpp b/arangod/Aql/IndexNode.cpp index 4bc2746be6..9e3606fac6 100644 --- a/arangod/Aql/IndexNode.cpp +++ b/arangod/Aql/IndexNode.cpp @@ -126,6 +126,8 @@ IndexNode::IndexNode (ExecutionPlan* plan, _condition = Condition::fromJson(plan, conditionJson); TRI_ASSERT(_condition != nullptr); + + specializeConditions(); } //////////////////////////////////////////////////////////////////////////////// @@ -175,6 +177,26 @@ void IndexNode::getVariablesUsedHere (std::unordered_set& vars) vars.erase(_outVariable); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief specialize condition for the indexes picked +//////////////////////////////////////////////////////////////////////////////// + +void IndexNode::specializeConditions () { + auto root = _condition->root(); + TRI_ASSERT(root->type == NODE_TYPE_OPERATOR_NARY_OR); + + size_t const n = root->numMembers(); + TRI_ASSERT(n == _indexes.size()); + + for (size_t i = 0; i < n; ++i) { + auto andNode = root->getMemberUnchecked(i); + + TRI_ASSERT(andNode->type == NODE_TYPE_OPERATOR_NARY_AND); + // std::cout << "ORIGINAL CONDITION:\n" << andNode << "\n"; + // std::cout << "SPECIALIZED CONDITION: " << _indexes[i]->simplifyCondition(andNode) << "\n"; + } +} + // Local Variables: // mode: outline-minor // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" diff --git a/arangod/Aql/IndexNode.h b/arangod/Aql/IndexNode.h index 58aa607e4a..7d5c2273e0 100644 --- a/arangod/Aql/IndexNode.h +++ b/arangod/Aql/IndexNode.h @@ -76,6 +76,8 @@ namespace triagens { TRI_ASSERT(_collection != nullptr); TRI_ASSERT(_outVariable != nullptr); TRI_ASSERT(_condition != nullptr); + + specializeConditions(); } IndexNode (ExecutionPlan*, triagens::basics::Json const& base); @@ -164,6 +166,18 @@ namespace triagens { return _indexes; } +// ----------------------------------------------------------------------------- +// --SECTION-- private methods +// ----------------------------------------------------------------------------- + + private: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief specialize condition for the indexes picked +//////////////////////////////////////////////////////////////////////////////// + + void specializeConditions (); + // ----------------------------------------------------------------------------- // --SECTION-- private variables // -----------------------------------------------------------------------------