mirror of https://gitee.com/bigwinds/arangodb
some bugfixes
This commit is contained in:
parent
118f924598
commit
b6c8d77d98
|
@ -1179,6 +1179,14 @@ AstNode* Ast::createNodeNop () {
|
|||
return const_cast<AstNode*>(&NopNode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the AST nop node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* Ast::getNodeNop () {
|
||||
return const_cast<AstNode*>(&NopNode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST n-ary operator node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1655,6 +1663,11 @@ TopLevelAttributes Ast::getReferencedAttributes (AstNode const* node,
|
|||
|
||||
AstNode* Ast::clone (AstNode const* node) {
|
||||
auto type = node->type;
|
||||
if (type == NODE_TYPE_NOP) {
|
||||
// nop node is a singleton
|
||||
return const_cast<AstNode*>(node);
|
||||
}
|
||||
|
||||
auto copy = createNode(type);
|
||||
|
||||
// special handling for certain node types
|
||||
|
|
|
@ -594,6 +594,12 @@ namespace triagens {
|
|||
|
||||
AstNode* createNodeNop ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the AST nop node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static AstNode* getNodeNop ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST n-ary operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1201,8 +1201,10 @@ bool AstNode::isFalse () const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a value node is of type attribute access that
|
||||
/// refers to the specified variable reference
|
||||
/// @brief whether or not a value node is of type attribute access that
|
||||
/// refers to any variable reference
|
||||
/// returns true if yes, and then also returns variable reference and array
|
||||
/// of attribute names in the parameter passed by reference
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool AstNode::isAttributeAccessForVariable (std::pair<Variable const*, std::vector<triagens::basics::AttributeName>>& result) const {
|
||||
|
@ -1223,10 +1225,17 @@ bool AstNode::isAttributeAccessForVariable (std::pair<Variable const*, std::vect
|
|||
expandNext = false;
|
||||
}
|
||||
else {
|
||||
// expansion
|
||||
// expansion, i.e. [*]
|
||||
TRI_ASSERT(node->type == NODE_TYPE_EXPANSION);
|
||||
TRI_ASSERT(node->numMembers() >= 2);
|
||||
|
||||
// check if the expansion uses a projection. if yes, we cannot use an index for it
|
||||
if (node->getMember(4) != Ast::getNodeNop()) {
|
||||
// [* RETURN projection]
|
||||
result.second.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! node->getMember(1)->isAttributeAccessForVariable(result)) {
|
||||
result.second.clear();
|
||||
return false;
|
||||
|
|
|
@ -507,7 +507,7 @@ namespace triagens {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a value node is of type attribute access that
|
||||
/// refers to a variable reference
|
||||
/// refers to any variable reference
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool isAttributeAccessForVariable () const {
|
||||
|
@ -530,8 +530,10 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a value node is of type attribute access that
|
||||
/// refers to the specified variable reference
|
||||
/// @brief whether or not a value node is of type attribute access that
|
||||
/// refers to any variable reference
|
||||
/// returns true if yes, and then also returns variable reference and array
|
||||
/// of attribute names in the parameter passed by reference
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool isAttributeAccessForVariable (std::pair<Variable const*, std::vector<triagens::basics::AttributeName>>&) const;
|
||||
|
|
|
@ -143,6 +143,11 @@ bool ConditionFinder::before (ExecutionNode* en) {
|
|||
SortCondition sortCondition(_sorts, _variableDefinitions);
|
||||
|
||||
if (condition->findIndexes(node, usedIndexes, sortCondition)) {
|
||||
bool reverse = false;
|
||||
if (sortCondition.isUnidirectional()) {
|
||||
reverse = sortCondition.isDescending();
|
||||
}
|
||||
|
||||
TRI_ASSERT(! usedIndexes.empty());
|
||||
std::cout << node->id() << " Number of indexes used: " << usedIndexes.size() << std::endl;
|
||||
// We either can find indexes for everything or findIndexes will clear out usedIndexes
|
||||
|
@ -153,7 +158,8 @@ bool ConditionFinder::before (ExecutionNode* en) {
|
|||
node->collection(),
|
||||
node->outVariable(),
|
||||
usedIndexes,
|
||||
condition.get()
|
||||
condition.get(),
|
||||
reverse
|
||||
));
|
||||
condition.release();
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "Aql/ExecutionBlock.h"
|
||||
#include "Aql/ExecutionNode.h"
|
||||
#include "Aql/IndexNode.h"
|
||||
#include "Aql/RangeInfo.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
#include "VocBase/shaped-json.h"
|
||||
|
||||
|
@ -87,7 +86,7 @@ namespace triagens {
|
|||
public:
|
||||
|
||||
IndexBlock (ExecutionEngine* engine,
|
||||
IndexNode const* ep);
|
||||
IndexNode const* ep);
|
||||
|
||||
~IndexBlock ();
|
||||
|
||||
|
@ -161,47 +160,6 @@ namespace triagens {
|
|||
|
||||
void sortConditions ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief andCombineRangeInfoVecs: combine the arguments into a single vector,
|
||||
/// by intersecting every pair of range infos and inserting them in the returned
|
||||
/// value if the intersection is valid.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<RangeInfo> andCombineRangeInfoVecs (std::vector<RangeInfo> const&,
|
||||
std::vector<RangeInfo> const&) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cartesian: form the cartesian product of the inner vectors. This is
|
||||
/// required in case a dynamic bound evaluates to a list, then we have an
|
||||
/// "and" condition containing an "or" condition, which we must then distribute.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IndexOrCondition* cartesian (std::vector<std::vector<RangeInfo>> const&) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief: subclass for comparing IndexAndConditions in _condition. Similar to
|
||||
/// OurLessThan in the SortBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SortFunc {
|
||||
public:
|
||||
SortFunc (std::vector<std::vector<size_t>> const& prefix,
|
||||
IndexOrCondition* condition,
|
||||
bool reverse)
|
||||
: _prefix(prefix),
|
||||
_condition(condition),
|
||||
_reverse(reverse) {
|
||||
}
|
||||
|
||||
bool operator() (size_t const&,
|
||||
size_t const&) const;
|
||||
|
||||
private:
|
||||
std::vector<std::vector<size_t>> const& _prefix;
|
||||
IndexOrCondition* _condition;
|
||||
bool const _reverse;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -67,6 +67,8 @@ void IndexNode::toJsonHelper (triagens::basics::Json& nodes,
|
|||
json("indexes", indexes);
|
||||
|
||||
json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE));
|
||||
|
||||
json("reverse", triagens::basics::Json(_reverse));
|
||||
|
||||
// And add it:
|
||||
nodes(json);
|
||||
|
@ -83,7 +85,7 @@ ExecutionNode* IndexNode::clone (ExecutionPlan* plan,
|
|||
|
||||
// TODO: check if we need to clone _condition or if we can reuse it here
|
||||
auto c = new IndexNode(plan, _id, _vocbase, _collection,
|
||||
outVariable, _indexes, _condition);
|
||||
outVariable, _indexes, _condition, _reverse);
|
||||
|
||||
cloneHelper(c, plan, withDependencies, withProperties);
|
||||
|
||||
|
@ -101,7 +103,8 @@ IndexNode::IndexNode (ExecutionPlan* plan,
|
|||
_collection(plan->getAst()->query()->collections()->get(JsonHelper::checkAndGetStringValue(json.json(), "collection"))),
|
||||
_outVariable(varFromJson(plan->getAst(), json, "outVariable")),
|
||||
_indexes(),
|
||||
_condition(nullptr) {
|
||||
_condition(nullptr),
|
||||
_reverse(JsonHelper::checkAndGetBooleanValue(json.json(), "reverse")) {
|
||||
|
||||
auto indexes = JsonHelper::checkAndGetObjectValue(json.json(), "indexes");
|
||||
|
||||
|
|
|
@ -62,13 +62,15 @@ namespace triagens {
|
|||
Collection const* collection,
|
||||
Variable const* outVariable,
|
||||
std::vector<Index const*> indexes,
|
||||
Condition const* condition)
|
||||
Condition const* condition,
|
||||
bool reverse)
|
||||
: ExecutionNode(plan, id),
|
||||
_vocbase(vocbase),
|
||||
_collection(collection),
|
||||
_outVariable(outVariable),
|
||||
_indexes(indexes),
|
||||
_condition(condition) {
|
||||
_condition(condition),
|
||||
_reverse(reverse) {
|
||||
|
||||
TRI_ASSERT(_vocbase != nullptr);
|
||||
TRI_ASSERT(_collection != nullptr);
|
||||
|
@ -198,6 +200,12 @@ namespace triagens {
|
|||
|
||||
Condition const* _condition;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the index sort order - this is the same order for all indexes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _reverse;
|
||||
|
||||
};
|
||||
|
||||
} // namespace triagens::aql
|
||||
|
|
|
@ -40,10 +40,15 @@ using namespace triagens::aql;
|
|||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortCondition::SortCondition (std::vector<std::pair<AstNode const*, bool>> const& expressions)
|
||||
: _expressions(expressions),
|
||||
_unidirectional(true),
|
||||
_onlyAttributeAccess(true) {
|
||||
_onlyAttributeAccess(true),
|
||||
_ascending(true) {
|
||||
|
||||
size_t const n = _expressions.size();
|
||||
|
||||
|
@ -80,11 +85,16 @@ SortCondition::SortCondition (std::vector<std::pair<AstNode const*, bool>> const
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortCondition::SortCondition (std::vector<std::pair<VariableId, bool>> const& sorts,
|
||||
std::unordered_map<VariableId, AstNode const*> const& variableDefinitions)
|
||||
: _expressions(),
|
||||
_unidirectional(true),
|
||||
_onlyAttributeAccess(true) {
|
||||
_onlyAttributeAccess(true),
|
||||
_ascending(true) {
|
||||
|
||||
size_t const n = sorts.size();
|
||||
|
||||
|
@ -92,6 +102,9 @@ SortCondition::SortCondition (std::vector<std::pair<VariableId, bool>> const& so
|
|||
if (_unidirectional && i > 0 && sorts[i].second != sorts[i - 1].second) {
|
||||
_unidirectional = false;
|
||||
}
|
||||
if (i == 0) {
|
||||
_ascending = sorts[i].second;
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
auto variableId = sorts[i].first;
|
||||
|
@ -128,6 +141,13 @@ SortCondition::SortCondition (std::vector<std::pair<VariableId, bool>> const& so
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortCondition::~SortCondition () {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -54,13 +54,24 @@ namespace triagens {
|
|||
SortCondition (SortCondition const&) = delete;
|
||||
SortCondition& operator= (SortCondition const&) = delete;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
explicit SortCondition (std::vector<std::pair<AstNode const*, bool>> const&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortCondition (std::vector<std::pair<VariableId, bool>> const&,
|
||||
std::unordered_map<VariableId, AstNode const*> const&);
|
||||
|
||||
~SortCondition () {
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the sort condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~SortCondition ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
|
@ -84,6 +95,26 @@ namespace triagens {
|
|||
return _unidirectional;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not all sort directions are ascending
|
||||
/// note that the return value of this function is only meaningful if the
|
||||
/// sort is unidirectional
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool isAscending () const {
|
||||
TRI_ASSERT(isUnidirectional());
|
||||
return _ascending;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not all sort directions are descending
|
||||
/// this is the reverse of isAscending()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool isDescending () const {
|
||||
return ! isAscending();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not there are fields
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -137,6 +168,13 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _onlyAttributeAccess;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not all sorts are in ascending order.
|
||||
/// this is only meaningful if the sort is unidirectional
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _ascending;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue