From 0dee54ee6f7d5083ff37e4b3bc499bba9deae551 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 13 Dec 2014 16:05:20 +0000 Subject: [PATCH] more bugfixes more tests --- arangod/Aql/ExecutionBlock.cpp | 73 ++++++++++++------- .../aql-queries-optimiser-in-noncluster.js | 26 +++++++ 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 8359c88abf..b162078818 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -1153,18 +1153,30 @@ bool IndexRangeBlock::initRanges () { } } } - // the elements of the direct product of the collector are and - // conditions which should be added to newCondition - auto indexAnds = cartesian(collector); - if (newCondition != nullptr) { - for (auto indexAnd: *indexAnds) { - newCondition->push_back(indexAnd); + bool isEmpty = false; + for (auto x: collector) { + if (x.empty()) { + isEmpty = true; + break; + } + } + + if (! isEmpty) { + // otherwise the condition is impossible to fulfil + // the elements of the direct product of the collector are and + // conditions which should be added to newCondition + auto indexAnds = cartesian(collector); + + if (newCondition != nullptr) { + for (auto indexAnd: *indexAnds) { + newCondition->push_back(indexAnd); + } + delete indexAnds; + } + else { + newCondition = indexAnds; } - delete indexAnds; - } - else { - newCondition = indexAnds; } } //_condition = newCondition.release(); @@ -1173,7 +1185,7 @@ bool IndexRangeBlock::initRanges () { _condition = newCondition; _freeCondition = true; } - + // remove duplicates . . . removeOverlapsIndexOr(*_condition); } @@ -1225,34 +1237,39 @@ std::vector IndexRangeBlock::andCombineRangeInfoVecs ( IndexOrCondition* IndexRangeBlock::cartesian ( std::vector> collector) { - + std::vector indexes; indexes.reserve(collector.size()); for (size_t i = 0; i < collector.size(); i++) { indexes[i] = 0; } - + auto out = new IndexOrCondition(); - - while (true) { - IndexAndCondition next; - for (size_t i = 0; i < collector.size(); i++) { - next.push_back(collector[i][indexes[i]].clone()); - } - out->push_back(next); - size_t j = collector.size() - 1; + try { while (true) { - indexes[j]++; - if (indexes[j] < collector[j].size()) { - break; + IndexAndCondition next; + for (size_t i = 0; i < collector.size(); i++) { + next.push_back(collector[i][indexes[i]].clone()); } - indexes[j] = 0; - if (j == 0) { - return out; + out->push_back(next); + size_t j = collector.size() - 1; + while (true) { + indexes[j]++; + if (indexes[j] < collector[j].size()) { + break; + } + indexes[j] = 0; + if (j == 0) { + return out; + } + j--; } - j--; } } + catch (...) { + delete out; + throw; + } } // insert the input rib into every ri in the IndexOrCondition . . . diff --git a/js/server/tests/aql-queries-optimiser-in-noncluster.js b/js/server/tests/aql-queries-optimiser-in-noncluster.js index ad3f1c8145..2032cf3a29 100644 --- a/js/server/tests/aql-queries-optimiser-in-noncluster.js +++ b/js/server/tests/aql-queries-optimiser-in-noncluster.js @@ -1028,6 +1028,32 @@ function ahuacatlQueryOptimiserInTestSuite () { assertEqual(expected, actual); ruleIsUsed(query); }, + + //TODO add SORT here + testSkiplistMoreThanOne6 : function () { + + for (var i = 1;i <= 100;i++) { + for (var j = 1; j <= 100; j++) { + for (var k = 1; k <= 10; k++) { + c.save({value1 : i, value2: j, value3: k, + value4: 'somethings' + 2*j }); + } + } + } + + c.ensureSkiplist("value1", "value2", "value3", "value4"); + + var query = "FOR x IN " + cn + " FILTER (x.value1 IN [PASSTHRU(1), PASSTHRU(2), PASSTHRU(3)] && x.value1 IN PASSTHRU([2, 3, 4]) && x.value2 == PASSTHRU(10) && x.value3 <= 2) || (x.value1 == 1 && x.value2 == 2 && x.value3 >= 0 && x.value3 == PASSTHRU(6) && x.value4 in ['somethings2', PASSTHRU('somethings4')] ) RETURN [x.value1, x.value2, x.value3, x.value4]"; + var expected = [ + [ 2, 10, 1, "somethings20" ], + [ 2, 10, 2, "somethings20" ], + [ 3, 10, 1, "somethings20" ], + [ 3, 10, 2, "somethings20" ], + [ 1, 2, 6, "somethings4" ] ]; + var actual = getQueryResults(query); + assertEqual(expected, actual); + ruleIsUsed(query); + }, //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////