1
0
Fork 0

some bugfixes

This commit is contained in:
Jan Steemann 2015-10-06 11:23:55 +02:00
parent 118f924598
commit b6c8d77d98
10 changed files with 121 additions and 58 deletions

View File

@ -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

View File

@ -594,6 +594,12 @@ namespace triagens {
AstNode* createNodeNop ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get the AST nop node
////////////////////////////////////////////////////////////////////////////////
static AstNode* getNodeNop ();
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST n-ary operator
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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
// -----------------------------------------------------------------------------

View File

@ -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");

View File

@ -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

View File

@ -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
// -----------------------------------------------------------------------------

View File

@ -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;
};
}