diff --git a/arangod/Aql/IndexBlock.cpp b/arangod/Aql/IndexBlock.cpp index 2007c8efab..dabaea6aef 100644 --- a/arangod/Aql/IndexBlock.cpp +++ b/arangod/Aql/IndexBlock.cpp @@ -387,7 +387,9 @@ bool IndexBlock::readIndex (size_t atMost) { return false; } - size_t lastIndexNr = _indexes.size(); + size_t lastIndexNr = _indexes.size() - 1; + bool isReverse = (static_cast(getPlanNode()))->_reverse; + bool isLastIndex = (_currentIndex == lastIndexNr && !isReverse) || (_currentIndex == 0 && isReverse); try { size_t nrSent = 0; while (nrSent < atMost && _iterator != nullptr) { @@ -399,9 +401,8 @@ bool IndexBlock::readIndex (size_t atMost) { TRI_IF_FAILURE("IndexBlock::readIndex") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - if (_currentIndex == 0 || - _alreadyReturned.find(indexElement) == _alreadyReturned.end()) { - if (_currentIndex < lastIndexNr) { + if (_alreadyReturned.find(indexElement) == _alreadyReturned.end()) { + if (! isLastIndex) { _alreadyReturned.emplace(indexElement); } diff --git a/js/server/tests/aql-optimizer-index-ranges.js b/js/server/tests/aql-optimizer-index-ranges.js index 9881898f22..20e30c87c5 100644 --- a/js/server/tests/aql-optimizer-index-ranges.js +++ b/js/server/tests/aql-optimizer-index-ranges.js @@ -88,11 +88,12 @@ function optimizerIndexesRangesTestSuite () { var results = AQL_EXECUTE(query[0]); assertEqual(query[1].length * 20, results.json.length, query); - var last = query[1][0]; + // var last = query[1][0]; results.json.forEach(function(value) { assertNotEqual(-1, query[1].indexOf(value)); - assertTrue(value >= last); - last = value; + // This is not guaranteed any more + // assertTrue(value >= last, query[0]); + // last = value; }); assertTrue(results.stats.scannedIndex > 0); @@ -136,11 +137,12 @@ function optimizerIndexesRangesTestSuite () { var results = AQL_EXECUTE(query[0]); assertEqual(query[1].length * 20, results.json.length, query); - var last = query[1][0]; + // var last = query[1][0]; results.json.forEach(function(value) { assertNotEqual(-1, query[1].indexOf(value)); - assertTrue(value >= last); - last = value; + // This is not guaranteed any more + // assertTrue(value >= last, query[0]); + // last = value; }); assertTrue(results.stats.scannedIndex > 0); diff --git a/js/server/tests/aql-queries-optimizer-in-noncluster.js b/js/server/tests/aql-queries-optimizer-in-noncluster.js index 626d5736b8..d2e9b821c5 100644 --- a/js/server/tests/aql-queries-optimizer-in-noncluster.js +++ b/js/server/tests/aql-queries-optimizer-in-noncluster.js @@ -1005,7 +1005,7 @@ function ahuacatlQueryOptimizerInTestSuite () { var expected = [ 1, 2 ]; var actual = getQueryResults(query); assertEqual(expected, actual); - ruleIsNotUsed(query); + ruleIsUsed(query); }, testOverlappingDynamicAndNonDynamic: function () { @@ -1031,6 +1031,11 @@ function ahuacatlQueryOptimizerInTestSuite () { var query = "FOR x in " + cn + " FILTER (x.value1 in [4,5] && x.value2 <= 2) || (x.value1 in [1,6] && x.value2 == 9) RETURN x.value1"; var expected = [ 1, 4, 4, 5, 5, 6 ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + return a - b; + }); assertEqual(expected, actual); ruleIsUsed(query); }, @@ -1061,6 +1066,11 @@ function ahuacatlQueryOptimizerInTestSuite () { var query = "FOR x in " + cn + " FILTER (x.value1 in [4,5] && x.value2 <= PASSTHRU(2)) || (x.value1 in [1,6] && x.value2 == 9) RETURN x.value1"; var expected = [ 1, 4, 4, 5, 5, 6 ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + return a - b; + }); assertEqual(expected, actual); ruleIsUsed(query); }, @@ -1091,6 +1101,11 @@ function ahuacatlQueryOptimizerInTestSuite () { var query = "FOR x in " + cn + " FILTER (x.value1 in [4,5] && x.value2 <= PASSTHRU(2)) || (x.value1 in [PASSTHRU(1),6] && x.value2 == 9) RETURN x.value1"; var expected = [ 1, 4, 4, 5, 5, 6 ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + return a - b; + }); assertEqual(expected, actual); ruleIsUsed(query); }, @@ -1112,6 +1127,14 @@ function ahuacatlQueryOptimizerInTestSuite () { [ 3, 10, 13, "somethings20" ], ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + if (a[0] !== b[0]) { + return a[0] - b[0]; + } + return a[2] - b[2]; + }); assertEqual(expected, actual); ruleIsUsed(query); }, @@ -1159,6 +1182,14 @@ function ahuacatlQueryOptimizerInTestSuite () { [ 3, 10, 2, "somethings20" ] ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + if (a[0] !== b[0]) { + return a[0] - b[0]; + } + return a[2] - b[2]; + }); assertEqual(expected, actual); ruleIsUsed(query); }, @@ -1176,7 +1207,7 @@ function ahuacatlQueryOptimizerInTestSuite () { 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 [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')] ) SORT x.value1 DESC RETURN [x.value1, x.value2, x.value3, x.value4]"; + var query = "FOR x IN " + cn + " FILTER (x.value1 IN [PASSTHRU(1), PASSTHRU(2), PASSTHRU(3)] && x.value1 IN [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')] ) SORT x.value1, x.value2, x.value3 DESC RETURN [x.value1, x.value2, x.value3, x.value4]"; var expected = [ [ 3, 10, 2, "somethings20" ], [ 3, 10, 1, "somethings20" ], @@ -1211,6 +1242,14 @@ function ahuacatlQueryOptimizerInTestSuite () { [ 3, 10, 2, "somethings20" ] ]; var actual = getQueryResults(query); + // Sorting is not guaranteed any more. + // We sort the result ourself + actual.sort(function (a, b) { + if (a[0] !== b[0]) { + return a[0] - b[0]; + } + return a[2] - b[2]; + }); assertEqual(expected, actual); ruleIsUsed(query); }