1
0
Fork 0
This commit is contained in:
Jan Steemann 2015-04-29 17:42:33 +02:00
parent c99cc2968f
commit 7783ed1b33
6 changed files with 63 additions and 28 deletions

View File

@ -238,7 +238,8 @@ static TRI_json_type_e GetNodeCompareType (AstNode const* node) {
////////////////////////////////////////////////////////////////////////////////
int triagens::aql::CompareAstNodes (AstNode const* lhs,
AstNode const* rhs) {
AstNode const* rhs,
bool compareUtf8) {
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
lhs = ResolveAttribute(lhs);
}
@ -251,6 +252,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
if (lType != rType) {
int diff = static_cast<int>(lType) - static_cast<int>(rType);
TRI_ASSERT_EXPENSIVE(diff != 0);
if (diff < 0) {
@ -268,6 +270,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
}
else if (lType == TRI_JSON_BOOLEAN) {
int diff = static_cast<int>(lhs->getIntValue() - rhs->getIntValue());
if (diff != 0) {
if (diff < 0) {
return -1;
@ -286,7 +289,10 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
}
}
else if (lType == TRI_JSON_STRING) {
return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue());
if (compareUtf8) {
return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue());
}
return strcmp(lhs->getStringValue(), rhs->getStringValue());
}
else if (lType == TRI_JSON_ARRAY) {
size_t const numLhs = lhs->numMembers();
@ -294,7 +300,8 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
size_t const n = ((numLhs > numRhs) ? numRhs : numLhs);
for (size_t i = 0; i < n; ++i) {
int res = triagens::aql::CompareAstNodes(lhs->getMember(i), rhs->getMember(i));
int res = triagens::aql::CompareAstNodes(lhs->getMember(i), rhs->getMember(i), compareUtf8);
if (res != 0) {
return res;
}
@ -314,7 +321,9 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
// for array AstNodes)
auto lJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE);
auto rJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE);
int res = TRI_CompareValuesJson(lJson, rJson, true);
int res = TRI_CompareValuesJson(lJson, rJson, compareUtf8);
if (lJson != nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, lJson);
}
@ -590,11 +599,12 @@ void AstNode::sort () {
auto const ptr = members._buffer;
auto const end = ptr + members._length;
std::sort(ptr, end, [] (void const* lhs, void const* rhs) {
auto const l = static_cast<AstNode const*>(lhs);
auto const r = static_cast<AstNode const*>(rhs);
return (triagens::aql::CompareAstNodes(l, r) < 0);
return (triagens::aql::CompareAstNodes(l, r, false) < 0);
});
setFlag(DETERMINED_SORTED, VALUE_SORTED);
@ -606,6 +616,7 @@ void AstNode::sort () {
std::string const& AstNode::getTypeString () const {
auto it = TypeNames.find(static_cast<int>(type));
if (it != TypeNames.end()) {
return (*it).second;
}

View File

@ -751,7 +751,7 @@ namespace triagens {
};
int CompareAstNodes (AstNode const*, AstNode const*);
int CompareAstNodes (AstNode const*, AstNode const*, bool);
}
}

View File

@ -1059,13 +1059,18 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
_hasV8Expression(false) {
auto trxCollection = _trx->trxCollection(_collection->cid());
if (trxCollection != nullptr) {
_trx->orderBarrier(trxCollection);
}
for (size_t i = 0; i < en->_ranges.size(); i++) {
std::vector<std::vector<RangeInfo>> const& orRanges = en->_ranges;
size_t const n = orRanges.size();
for (size_t i = 0; i < n; i++) {
_condition->emplace_back(IndexAndCondition());
for (auto ri: en->_ranges[i]) {
for (auto const& ri: en->_ranges[i]) {
_condition->at(i).emplace_back(ri.clone());
}
}
@ -1074,7 +1079,6 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
removeOverlapsIndexOr(*_condition);
}
std::vector<std::vector<RangeInfo>> const& orRanges = en->_ranges;
TRI_ASSERT(en->_index != nullptr);
_allBoundsConstant.clear();
@ -1083,8 +1087,9 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
// Detect, whether all ranges are constant:
for (size_t i = 0; i < orRanges.size(); i++) {
bool isConstant = true;
std::vector<RangeInfo> const& attrRanges = orRanges[i];
for (auto r : attrRanges) {
for (auto const& r : attrRanges) {
isConstant &= r.isConstant();
}
_anyBoundVariable |= ! isConstant;

View File

@ -1679,8 +1679,8 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
if (enumCollVar != nullptr) {
foundSomething = true;
std::unordered_set<Variable*> varsUsed
= Ast::getReferencedVariables(lhs);
std::unordered_set<Variable*>&& varsUsed = Ast::getReferencedVariables(lhs);
if (varsUsed.find(const_cast<Variable*>(enumCollVar))
== varsUsed.end()) {
// Found a multiple attribute access of a variable and an
@ -1847,9 +1847,7 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
for (size_t i = 0; i < n; i++) {
RangeInfo ri(enumCollVar->name,
attr.substr(0, attr.size() - 1),
RangeInfoBound(rhs->getMember(i), true),
RangeInfoBound(rhs->getMember(i), true),
true);
RangeInfoBound(rhs->getMember(i), true));
// the following does not seem to be necessary here, but will slow things down
// considerably if the array is very big
// rimv->differenceRangeInfo(ri);
@ -1863,9 +1861,7 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
else {
RangeInfo ri(enumCollVar->name,
attr.substr(0, attr.size() - 1),
RangeInfoBound(rhs, true),
RangeInfoBound(rhs, true),
true);
RangeInfoBound(rhs, true));
rimv->differenceRangeInfo(ri);
if (ri.isValid()) {
std::unique_ptr<RangeInfoMap> temp(new RangeInfoMap(ri));
@ -2105,14 +2101,14 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
// results), for example
// x.a == 1 || y.c == 2 || x.a == 3
if (_rangeInfoMapVec->isMapped(var->name)) {
std::vector<size_t> const validPos = _rangeInfoMapVec->validPositions(var->name);
std::vector<size_t>&& validPos = _rangeInfoMapVec->validPositions(var->name);
// are any of the RangeInfoMaps in the vector valid?
if (! _canThrow) {
if (validPos.empty()) { // ranges are not valid . . .
auto parents = node->getParents();
for (auto x : parents) {
for (auto const& x : parents) {
auto noRes = new NoResultsNode(_plan, _plan->nextId());
_plan->registerNode(noRes);
_plan->insertDependency(x, noRes);
@ -2127,8 +2123,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
// note: prefixes are only used for skiplist indexes
// for all other index types, the prefix value will always be 0
node->getIndexesForIndexRangeNode(
_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
node->getIndexesForIndexRangeNode(_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
// make one new plan for every index in <idxs> that replaces the
// enumerate collection node with a IndexRangeNode ...
@ -4347,7 +4342,7 @@ struct RemoveRedundantOr {
// returns false if the existing value is better and true if the input value is
// better
bool compareBounds (AstNodeType type, AstNode const* value, int lowhigh) {
int cmp = CompareAstNodes(bestValue, value);
int cmp = CompareAstNodes(bestValue, value, true);
if (cmp == 0 && (isInclusiveBound(comparison) != isInclusiveBound(type))) {
return (isInclusiveBound(type) ? true : false);

View File

@ -427,7 +427,7 @@ void RangeInfoMap::attributes (std::unordered_set<std::string>& set,
std::unordered_map<std::string, RangeInfo> const* map = find(var);
if (map != nullptr) {
for (auto x: *map) {
for (auto const& x: *map) {
set.emplace(x.first);
}
}
@ -527,7 +527,9 @@ bool RangeInfoMapVec::isMapped (std::string const& var) const {
std::vector<size_t> RangeInfoMapVec::validPositions (std::string const& var) const {
std::vector<size_t> valid;
for (size_t i = 0; i < _rangeInfoMapVec.size(); i++) {
size_t const n = _rangeInfoMapVec.size();
for (size_t i = 0; i < n; i++) {
if (_rangeInfoMapVec[i]->isValid(var)) {
valid.emplace_back(i);
}

View File

@ -373,8 +373,8 @@ namespace triagens {
RangeInfo (std::string const& var,
std::string const& attr,
RangeInfoBound low,
RangeInfoBound high,
RangeInfoBound const& low,
RangeInfoBound const& high,
bool equality)
: _var(var),
_attr(attr),
@ -414,6 +414,28 @@ namespace triagens {
}
}
}
RangeInfo (std::string const& var,
std::string const& attr,
RangeInfoBound const& bound)
: _var(var),
_attr(attr),
_valid(true),
_defined(true),
_equality(true) {
// must be an equality here!
TRI_ASSERT(bound.inclusive());
if (bound.isConstant()) {
_lowConst.assign(bound);
_highConst.assign(bound);
}
else {
_lows.emplace_back(bound);
_highs.emplace_back(bound);
}
}
RangeInfo (std::string const& var,
std::string const& attr)