diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 5176342356..52ba5fcddf 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -1139,10 +1139,6 @@ class FilterToEnumCollFinder : public WalkerWorker { if (node->type == NODE_TYPE_OPERATOR_BINARY_EQ) { auto lhs = node->getMember(0); auto rhs = node->getMember(1); - if (rhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) { - lhs = node->getMember(1); - rhs = node->getMember(0); - } if (rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { buildRangeInfo(rhs, enumCollVar, attr, isOrCondition); if (enumCollVar != nullptr) { @@ -1163,6 +1159,26 @@ class FilterToEnumCollFinder : public WalkerWorker { } } } + if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { + buildRangeInfo(lhs, enumCollVar, attr, isOrCondition); + if (enumCollVar != nullptr) { + std::unordered_set varsUsed + = Ast::getReferencedVariables(rhs); + if (varsUsed.find(const_cast(enumCollVar)) + == varsUsed.end()) { + // Found a multiple attribute access of a variable and an + // expression which does not involve that variable: + insert(enumCollVar->name, + attr.substr(0, attr.size() - 1), + RangeInfoBound(rhs, true), + RangeInfoBound(rhs, true), + true, + isOrCondition); + enumCollVar = nullptr; + attr.clear(); + } + } + } return; } diff --git a/arangod/Aql/RangeInfo.cpp b/arangod/Aql/RangeInfo.cpp index 53c741f108..ed0d201a9c 100644 --- a/arangod/Aql/RangeInfo.cpp +++ b/arangod/Aql/RangeInfo.cpp @@ -465,7 +465,7 @@ void RangeInfoMapVec::insertDistributeAndIntoOr (std::vector ranges) for (size_t j = 1; j < ranges.size(); j++) { RangeInfoMap* rim = sample->clone(); rim->insert(ranges[j]); // here we intersect with any existing values - _rangeInfoMapVec.push_back(rim); + _rangeInfoMapVec.emplace_back(rim); } } } @@ -474,7 +474,7 @@ void RangeInfoMapVec::insertDistributeAndIntoOr (std::vector ranges) for (auto x: ranges) { RangeInfoMap* rim = new RangeInfoMap(); rim->insert(x); - _rangeInfoMapVec.push_back(rim); + _rangeInfoMapVec.emplace_back(rim); } } } diff --git a/arangod/Aql/RangeInfo.h b/arangod/Aql/RangeInfo.h index 2d408474a3..6b12767adf 100644 --- a/arangod/Aql/RangeInfo.h +++ b/arangod/Aql/RangeInfo.h @@ -529,8 +529,24 @@ namespace triagens { } RangeInfo clone () { - //TODO improve this - return RangeInfo(this->toJson()); + RangeInfo copy(_var, _attr); + + copy._lowConst.assign(_lowConst); + copy._highConst.assign(_highConst); + + for (auto x: _lows) { + copy._lows.emplace_back(x); + } + for (auto x: _highs) { + copy._highs.emplace_back(x); + } + copy._valid = _valid; + copy._defined = _defined; + copy._equality = _equality; + + return copy; + //FIXME the following should work but doesn't!! + //return RangeInfo(this->toJson()); } ////////////////////////////////////////////////////////////////////////////////